I've really gotten into the DI/IoC things - it makes some things a lot easier. However, I have a few inherited classes that implement a class with a required parameterless constructor, I thus use a service locator to get what I want:
MyMembershipProivder() : MyMembershipProvider(ServiceLocator.Current.GetInstance<...>){}
MyMembershipProivder(IMemberRepo memberRepo){...}
Works perfect. However, since I'm also using MVC3 DependencyResolver I find myself no other way but to do:
var locator = new NinjectServiceLocator(kernel);
DependencyResolver.SetResolver(locator);
ServiceLocator.SetLocatorProvider(() => locator);
DependencyResolver gets used within the MVC app and the ServiceLocator gets used throughout the various class libraries.
Is this the ideal way to do this? Am I missing something?
Update
In the example above, the class is a custom asp.net mebership provider. The asp.net membership provider factory requires for my custom provider to have a parameterless constructor, forcing me to use the service locator to inject the repository that it uses internally.
You don't need the parameterless constructor, the Dependency Resolver will inject your dependency into the constructor:
MyMembershipProivder(IMemberRepo memberRepo){...}
You can replace the default controller factory (to use parameterless constructors in your controllers):
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
You wont need to replace the default controller factory, see Linkgoron's comment below.
Anyway using the Dependency Resolver for your MVC application and the Service Locator for your class libraries is fine, I think.
Hope this helps.
It seems as if you don't really have a choice, unless you can refactor your application to use DI from the start. So, I guess using custom a Service Locator is your best bet.
Although, if the classes you've "inherited" are the controller classes you can just remove the default constructors and be done with it, as MVC will handle everything for you.
I've never seen the ServiceLocator class, is it this?
EDIT:
As I've said, I don't see that you have any other option for decoupling. Service location is probably your best bet, without introducing too much bloat and complexity.
Stuff that's implemented as something built into the .Net FW you should look for specific solutions like the one presented for the Membership Provider.
Related
In my project I have the interface IProcess and a lot of classes implementing this interface. I need to register all those implementations. The following code is working fine for me:
Container.Register(Component.For<IProcess>().Named("SampleProcess").ImplementedBy<SampleProcess>());
Container.Register(Component.For<IProcess>().Named("SampleProcess2").ImplementedBy<SampleProcess2>());
However using this approach for registering is tedious if I have a lot of implementations. Therefore I am looking for a registration method to register all implementations of IProcess in a given assembly by name. The name that should be used for the registration key is just the class name.
Can someone pls give me a hint where to look for?
Sounds like a classic scenario for the convention registration API.
container.Register(
Classes.FromThisAssembly()
.BasedOn<IProcess>()
.WithServiceBase()
// and then if you *really* need to explicitly control naming
.Configure(c => c.Named(c.Implementation.Name)
)
Generally explicitly naming your components shouldn't be used, unless you have multiple components with the same implementation class, so just make sure you really need it.
In my project I using chain of responsibility designing pattern for which I need to create multiple handlers which will implement same interface. In .net application(not .net core) I would have used DI using UnityContainer where I could have resolved handlers using named parameter. But in .net core I can not do that. Now I have few options to use other DI libraries like Autofac, Structuremap or create factory method which can give me objects based on name passed. Please help me in picking right approach between these or suggest something better if available. I have not used Autofac or Structuremap so I very little idea of same. Thanks.
For the most part, all DI tools out there achieve the same thing with different APIs. These days the differences are highlighted by your needs.
StructureMap or Autofac are both good candidates. It all boils down to "flavor".
Check this article. I think is a good one. Configuration comparison dependency injection containers
Again, don't stress over them unless you need a very very specific feature form one of them.
I would do Autofac just because I haven't had the need for something else however, I would not hesitate to use StructureMap, Ninject or whatever new kid on the block is brought up.
I am trying to incorporate Microsoft.Extensions.DependencyInjection into an existing ASP.NET 4.6.1 app.
I know that while .NET Core has it built-in, for 4.6.1 you need to create some initial classes as outlined in http://scottdorman.github.io/2016/03/17/integrating-asp.net-core-dependency-injection-in-mvc-4/. (The article seems to be out of date since the sample code does not show implementation of BeginScope() and Dispose() for IDependencyResolver. If anybody has more updated examples that would be appreciated.)
"Services" accessed by controllers where you are creating instances via constructors is fairly simple but my problem is when I need an instance of "something" that is from a property or method of an existing object.
For example, I have a inherited DbContext that needs an instance of System.Security.Principal.IIdentity that comes from the logged in user.
Another example is an instance of ApplicationUser. ApplicationUser inherits IdentityUser and the current user can be found by calling FindById() method of AppUserManager.
While AppUserManager can easily be instantiated using DI, how can I use DI the inject the output of the FindById() method? I cannot seem to find any documentation or sample code about this for Microsoft based framework. Other frameworks like Unity seem to support Property-based injection.
In essence, can DI be used with all existing classes or do you specifically need to code out the classes to support DI from the beginning? (i.e. only expect parameters to be passed in via constructors and make sure those instances themselves are created via constructors).
The very simple and short answer to your question "Does Microsoft DependencyInjection support non-constructor injection?" is, no.
Out-the-box Microsoft DI does not currently support property injection like other frameworks such as Ninject. If you need that feature, I suggest using those frameworks instead (I cant imagine MS has any plans to add property injection any time soon).
Your other option is to consider how you can refactor your code to use constructor injection instead which is the preferred method
I have an MVC application with a typical architecture...
ASP.NET MVC Controller -> Person Service -> Person Repository -> Entity Framework DB Context
I am using Castle Windsor and I can see the benefit of using this along with a ControllerFactory to create controller with the right dependencies. Using this approach the Controller gets a Service injected, which in turn knows how to construct the right Repository, which in turn knows the correct DbContext to use.
The windsor config is something like this...
dicontainer = new WindsorContainer();
dicontainer.Register(Component.For<IPersonService>().ImplementedBy<PersonService>());
dicontainer.Register(
Component.For<IPersonRepository>().UsingFactoryMethod(
() => new PersonRepository(new HrContext("connectionString"))));
It this the right way to do it? I don't like the UsingFactoryMethod, but can't think of another way.
Also, what if the Repository needed a dependency (say ILogger) that was not needed by the service layer? Does this mean I have to pass the ILogger into the service layer and not use it. This seems like a poor design. I'd appreciate some pointers here. I have read loads of articles, but not found a concrete example to verify whether I am doing this right. Thanks.
I try to avoid using factory methods (as you mentioned you felt this smelled funny). To avoid this, you could create a database session object that creates a new DbContext. Then your repositories just need to get an instance of IDbSession and use its dbContext property. Then, you can also easily control the scope of the IDbSession object (don't use singleton because it's not thread safe).
I wanted to make that point so that I could make this more important point... Make your constructors take in only objects that are registered in the DI container (no options or configurations in constructors). Options and configurations should be read/writen in classes whose sole purposes it is to read/write those values. If all classes follow this model, then your DI registration becomes easy and classes can just add whatever dependencies they need in their constructors.
If you are trying to use a third party library that has options in constructors, wrap that class in your own class that has an easy to consume constructor and uses a configuration class to read the values needed to pass to the third party library. This design also introduces a layer of abstraction between your code and the third party library which can then be used to more easily swap (or stub) third party libraries when necessary.
I have a a model class that needs access to my repository class (used for DB access).
I have created an interface for my repository and have successfully configured Castle Windsor to inject my the appropriate IRepository-based class into my controllers via a custom ControllerFactory.
I'm having a little more trouble figuring out how to do the same thing with my model.
Does anyone know of a way to use Windsor to inject a dependency into an MVC model?
As an aside, the reason I need Windsor to handle this is because MVC automatically instantiates an instance of my model when data is posted to my controller, and this automatic instantiation doesn't allow for me to pass any constructor parameters.
You may want to take a look at MVC Contrib's Castle Binder.
However, personally, I think that Models should be simple POCO's, or dumb containers of data, free of any DI. In this approach, it is the Controller's responsibility to read, manipulate and persist data.