2

I have been following this post to learn about DI with AutoFac. My DB context is registered in Startup.cs like this:

builder.RegisterType<MyDb>().As<IMyDbCtx>().InstancePerRequest();

I also followed the instructions to create the ApplicationUserStore class, and registered this type like so:

builder.RegisterType<ApplicationUserStore>().As<IUserStore<ApplicationUser>>().InstancePerRequest();

This was all fine until I realized that ApplicationUserStore is expecting a concrete DbContext in it's constructor to pass to its base constructor:

public ApplicationUserStore(MyDb context)
            : base(context)
        {
        }

When I run the application and try loading the registration page, this is the error I see:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'TestApp.Service.IdentityConfig.ApplicationUserStore' can be invoked with the available services and parameters: Cannot resolve parameter 'TestApp.Data.MyDb context' of constructor 'Void .ctor(MyApp.Data.MyDb)'.

This is breaking, I assume, because I already set up MyDb as a IMyDbCtx, so it won't accept the concrete type. This is good because I don't want to be inconsistent by injecting abstractions in some spots and implementations in others.

Does anyone have any ideas on how I can pass in an IMyDbCtx to the UserStore ctor, particularly with AutoFac?

skoh
  • 31
  • 4

2 Answers2

1

This is not an ideal solution, but I decided to cast the interface to the concrete type when the parameter is passed to the base constructor:

public ApplicationUserStore(IMyDbCtx context) : base((MyDb)context) { }

skoh
  • 31
  • 4
  • What is the point of having an interface over `DbContext`? Register your DbContext `.AsSelf()` and inject it directly. What does your `IMyDbCtx` interface do, anyway? – trailmax Sep 22 '15 at 20:26
  • FYI I'm new and trying to figure out a good design. The UoW as a contract described [here](http://stackoverflow.com/questions/21349950/entity-framework-6-code-first-is-repository-implementation-a-good-one) sounded like a good idea. I was trying to hide EF specifics (DbContext) as much as possible in my service layer, but this is posing a challenge. – skoh Sep 22 '15 at 22:56
  • EF is already implementing UoW, don't re-invent your own, especially for classes that you don't control that expect a certain DbContext injected. – trailmax Sep 22 '15 at 23:02
  • I see your point. I wanted to avoid coupling other layers that use my DAL to EF details, but I guess it's not that big of a deal. – skoh Sep 24 '15 at 03:23
  • The interface is helpful for Test units and Mocking – Mohamed Farrag Mar 21 '17 at 11:24
0

You can register your type MyDb under as many aliases as you wish:

builder.RegisterType<MyDb>()
  .As<MyDb>()
  .As<IMyDbCtx>()
  .InstancePerRequest();

In this case Autofac can resolve Application User Store. But it kills the whole idea of dependency injection, because you feed the concrete type.

Alex Zhevzhik
  • 3,347
  • 19
  • 19
  • `DbContext` from Entity Framework is not meant to be behind an interface this way. And "Dependency Injection" does not mean create an interface for every class you have. – trailmax Sep 22 '15 at 20:27
  • Yes, I know. But it's pointless to have an interface and inject the implementation, unless it's some very specific case (For example, the interface is for injecting by other modules, but some internal types may inject the implementation). I encourage the topic starter to be sure that this is "specific" case. And if it's not - try to get rid of the interface or inject the implementation. – Alex Zhevzhik Sep 23 '15 at 07:16