0

We have a multi tier app that have a lot of dependencies. We use Autofac and MEF so that all the components can register their own dependencies in init modules. That way, the "higher" components doesn't have to know all the dependencies graph. It just register the component it needs, and the rest comes along. At the higher level, there is a WCF facade app that imports almost all of our DLL and register them with Autofac. It works fine, but since the repository layer depends on EntityFramework, I get the infamous error :

No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'. Make sure the provider is registered in the 'entityFramework' section of the application config file

The only way I found not to have this error is to directly reference EntityFramework.SqlServer in the WCF facade project. But I'd like to leave the responsabllity of this to the repo layer itself. So I would need a way to somehow load the dll and register the System.Data.SqlClient. Does anyone know a way to do so or am I just dreaming ? It's my first time with both Autofac and MEF and I'm far from an expert in DI.

Since it is highly conceptual, here is a little schema with source code to help you understand better : Conceptual map

Get readeable version here

Patrice Cote
  • 3,572
  • 12
  • 43
  • 72
  • You could probably distill the question a bit...sounds like you're trying to ask about how to import a DLL that uses Entity Framework without referencing `EntityFramework.SqlServer` in other projects? – jjj May 26 '15 at 22:50
  • Yes. But by using Autofac and MEF as decribed in my question. This is a requirement by my client, I don't have control over this. The binaries lives in a separate folder and are not imported in the "bin" folder. – Patrice Cote May 27 '15 at 14:00

1 Answers1

1

Perhaps you could take a look at Code-Based Configuration.

  1. Create a custom DbConfiguration

    public class MyDbConfiguration : DbConfiguration 
    { 
        public MyDbConfiguration() 
        { 
            // Other configuration stuff like SetDefaultConnectionFactory
            SetProviderServices(
                "System.Data.SqlClient", 
                System.Data.Entity.SqlServer.SqlProviderServices.Instance);
        } 
    } 
    
  2. Add a DbConfigurationTypeAttribute to your DbContext

    [DbConfigurationType(typeof(MyDbConfiguration))] 
    public class MyDbContext : DbContext 
    { }
    

    or

    [DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")] 
    public class MyDbContext : DbContext 
    { }
    
  3. Remove entityFramework configuration from the app.config file

Edit

For your top level project to find assemblies referenced by your MEF components, if you're able/willing to add something to the app.config, maybe you could use something like:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="Libs"/>
  </assemblyBinding>
</runtime>

It would still be a dependency, in a sense, but you do have to add a search path for MEF...

https://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.110%29.aspx
How can MEF resolve dependencies of assemblies that don't live at the root of the application?

Community
  • 1
  • 1
jjj
  • 4,822
  • 1
  • 16
  • 39
  • I already do it. It's not the configuration that is the problem, it's the fact that EntityFramework.SqlServer is not referenced in the project. As soon as I reference it, it works. Problem is, we don't want to reference it at the top level. That the great advantage of composition (MEF), top level components don't have to know the dependencies of its dependencies. Every components is responsible to register its own dependencies, so it alls drills down whenever you register it. – Patrice Cote May 27 '15 at 14:09
  • Ah okay, it's an assembly resolution thing. Sorry, I misunderstood. Maybe you would be willing to look at setting the assembly probing path. – jjj May 27 '15 at 14:17
  • Yes @jjj that's an assembly resolution problem. I don't know about assembly probing path ? I'll google it first and come back to you tomorrow. Thanks ! – Patrice Cote May 27 '15 at 19:37
  • I just saw it. That looks promising, although I'll have to test it to see if it works with the Autofac LifetimeScope resolver. – Patrice Cote May 28 '15 at 16:06