From Using the Simple Injector in Simple Injector documentation:
Note: Calling the GetInstance method in the constructor is suboptimal and should be avoided whenever possible. With ASP.NET Web Forms however, it is hard to completely avoid this. Please see the Integration Guide for alternatives.
Why exactly is it suboptimal?
I did notice that this kind of usage can cause issues due to the intentional limitation that the container is locked after the first call to resolve. Thus if you register A, then create a collection of ISomething - one of which has a dependency on A - and then you register that collection using RegisterAll(), then you run into trouble because one of the ISomethings resolves A, preventing the subsequent registration of the collection.
However I imagine there is more to "suboptimal" than this.
Calling back into the container from within the constructor of your type is sub optional, because:
You render your DI library blind, and disallow it to see which dependencies a type has, which makes it impossible to warn you about any misconfigurations you might have made.
Makes it impossible for the DI library to optimize the object graph construction for you.
Makes it impossible to apply features such as Context Based Injection that work by changing the expression tree before it gets compiled to code.
You make it harder to unit test code that calls into the container.
Calling back into the container is an anti-pattern called Service Locator.
Unfortunately, the documentation you are pointing at is a bit outdated and in general we advice against using this type of construct. The ASP.NET Web Forms Integration page therefore describes a better solution for this using explicit property injection.
Related
I am learning DI in .Net Core and I find all examples only use one instance of ServiceCollection. I wonder whether this instance must be a singleton but I get confused because we can invoke new. Probably because of my lack of knowledge, it really makes sense to have multiple instances of ServiceCollection. Any comment and suggestion are welcome!
It's both more efficient and less Dangerous than creating multiple service providers. Creating one instance allows you to have all your services in one place instead of divided over multiple provider instances.
A service provider doesn't have to be a singleton, but it makes users of dependency injection frameworks less likely go down the bad road.
The bad road in this case is separating your dependencies and later having to pass/ know the right dependency provider to choose from when getting your dependencies.
This makes your code more complicated than it has to be, as well as creating no benefit for both you and especially other people who will join you on your project and have to figure out which provider had the object which can access the database.
Most frameworks have their service providers accessible statically which also allows you to retrieve services and merge the service provider into your project far easier. Having multiple instances would make this difficult.
Normally with dependency injection you would for example pass it directly in your constructor.
So in short:
It's convenient
efficient
easy to read and understand
makes it difficult to use it the wrong way
Allows it to be easily used as a static object
Reading the Simple injector docs to get a handle on how it all works and I read the below paragraph. I understand what its explaining apart from the part in bold. What does it mean?
The technique for keeping this dependency to a minimum can be achieved by designing the types in your application around the constructor injection pattern: Define all dependencies of a class in the single public constructor of that type; do this for all service types that need to be resolved and resolve only the top most types in the application directly (i.e. let the container build up the complete graph of dependent objects for you)
Ignoring my lack of understanding regarding the sentence above I ploughed on but when trying to set up Simple injector for Web api came across this line of code container.RegisterWebApiControllers(GlobalConfiguration.Configuration); With this explanation
Because controllers are concrete classes, the container will be able to create them without any registration.
Does this mean if I have a bunch of classes that don't rely on an interface, I can create them using a single line of code? (if so how, should I).
What this means is a good practice of not relying on the DI-container in your code apart from some top-level where you have to do that to "kick-start" the application.
That will mean that all your classes will just have constructor dependencies in the form of interfaces and will not do Container.Resolve. This will only be called on the top level of you application.
In some frameworks you won't even have to do that yourself because it's a part of how framework operates. As far as I remember in .Net core e.g. you won't need to do a resolve, but it will happen inside framework when the controllers will be initiated.
Because controllers are concrete classes, the container will be able
to create them without any registration.
This means you won't have to register the controllers themselves in the container. Container will only resolve controller dependencies themselves, create controllers and pass all of the resolved dependencies in them.
P.S. Resolving only in the root of you application is nothing specific for the SimpleInjector. It is a good practice that can be applied to any container and SimpleInjector can be used even if you don't follow it, which probably no one these days would recommend.
do this for all service types that need to be resolved and resolve only the top most types in the application directly
What this means is that, once you solely use Constructor Injection as a way for a class to get a hold of its dependencies, you will end up building object graphs that are potentially many layers deep. Take this object graph for instance:
new HomeController(
new ProductService(
new SqlProductRepository(
new CommerceContext(connectionString)),
new AspNetUserContextAdapter(
httpContextAccessor)));
PRO TIP: Did you know that you can let Simple Injector visualize your object graphs for you inside the debugger? This is explained here.
Here you see that HomeController has one dependency (IProductService) that it gets through its constructor. ProductService itself has two dependencies (IProductRepository and IUserContext) that are as well supplied through its constructor. This can go many layers deep.
Having Constructor Injection as the sole means to supply dependencies to a class means that the class is not allows to request them itself by calling back into the Container. This is a well-established anti-pattern called Service Locator. Constructor Injection simplifies your classes and allows the Container to analyze the object graph for you and detect any anomalies.
and resolve only the top most types in the application directly
When the whole object graph is constructed using Constructor Injection, it means that you only have to ask for a HomeController, which is the top most type in the graph. Nothing depends on HomeController; HomeController depends on everything (implicitly). All application behavior is invoked through these top most types. In an MVC application these typically are controllers, HTTP handlers and modules.
Because controllers are concrete classes, the container will be able to create them without any registration.
This statement is a bit misleading. Yes, it is true that Simple Injector will be able to create a requested concrete type for you, even if that type isn't registered. As explained here in the documentation however, it is best to always register your root types in the container. This ensures that the container knows about those types and it allows analysis and verification on those types as well. Not registering those concrete root types will give you a false sense of security when you call container.Verify(). Verify is only able to verify on the registrations that it knows of. When an unregistered concrete type is referenced as a dependency, the container still knows about it, but that obviously doesn't hold for root types, since nothing depends on them.
WARNING: In Simple Injector v5, this behavior is likely going to change. By default, Simple Injector v5 will probably not allow concrete unregistered root types to be resolved. see
I'm moving from StructureMap 2.x to 3.x. One major change is that using ObjectFactory results in the following warning:
'StructureMap.ObjectFactory' is obsolete: 'ObjectFactory
will be removed in a future 4.0 release of StructureMap. Favor the
usage of the Container class for future
work'
So in most cases, the resolution is fairly easy: pass through IContainer as a constructor. Unfortunately this is not feasible for ASMX web serivces or attributes, both of which require a default constructor. That means I'm probably stuck with the Service Locator Pattern, property injection, or writing my own ObjectFactory implementation.
What's the preferred way to deal with this unfortunate problem?
Edit: It's worth mentioning that my container does an Assembly scan.
Per Jeremy Miller, himself:
Assembly scanning isn’t cheap and you (almost?) always wanna cache the
results. So, yeah, in that case you’re going to have to write your
own ObjectFactory. Someday all that bad old MS tech will go away.
So in this case, this implementation is what should be done.
The cleanest way I have seen to deal with this is to use .NET routing to take control of the entry point, then make a custom PageHandlerFactory implementation that takes the DI container as a dependency.
The custom page handler factory will then property inject the page/service after it is instantiated but before any of its events are called.
This is almost exactly the same way that IControllerFactory works with DI in MVC. In MVC, the container is injected into a custom IControllerFactory implementation at application startup, which effectively makes it a part of the application's composition root. In the case of ASP.NET, the IRouteHandler would effectively be part of the composition root.
I was unable to find a link to the source where I originally saw that implementation. But this one is pretty close. The primary difference is that one tries to use constructor injection, but the downside is that it requires full trust to do. I believe if you stick with property injection, you can do it with partial trust.
I'm writing a C# ASP.NET MVC web application using SOLID principles.
I've written a ViewModelService, which depends on a AccountService and a RepositoryService, so I've injected those two services in the the ViewModelServer.
The PermissionService depends on the HttpContextBase in order to use GetOwinContext() to get an instance of the UserManager. The controller has an instance of HttpContextBase that needs to be used - so it seems like I have to inject the HttpContextBase instance into the ViewModelService which then injects it into the PermissionService.
So, in terms of code I have:
public ViewModelService
public CategoryRepository(ApplicationDbContext context, IPermissionService permissionservice)
public AccountService(HttpContextBase httpcontext, IPrincipal securityprincipal)
to instantiate the ViewModelService, I then do this:
new ViewModelService(
new CategoryRepository(
new ApplicationDbContext(),
new PermissionService(
new AccountService(HttpContext, Thread.CurrentPrincipal),
new UserPasswordRepository(new ApplicationDbContext()),
new ApplicationSettingsService())),
new PasswordRepository(
new ApplicationDbContext(),
new PermissionService(
new AccountService(HttpContext, Thread.CurrentPrincipal),
new UserPasswordRepository(new ApplicationDbContext()),
new ApplicationSettingsService())),
new ModelValidatorService());
Should a dependency be injected from that many "levels" up, or is there a better way?
There's a balance to be struck.
On the one hand, you have the school of thought which would insist that all dependencies must be exposed by the class to be "properly" injected. (This is the school of thought which considers something like a Service Locator to be an anti-pattern.) There's merit to this, but taken to an extreme you find yourself where you are now. Just the right kind of complexity in some composite models, which themselves have composite models, results in aggregate roots which need tons of dependencies injected solely to satisfy dependencies of deeper models.
Personally I find that this creates coupling in situations like this. Which is what DI is intended to resolve, not to create.
On the other hand, you have the school of thought which allows for a Service Locator approach, where models can internally invoke some common domain service to resolve a dependency for it. There's merit to this, but taken to an extreme you find that your dependencies are less known and there's a potential for runtime errors if any given dependency can't be resolved. (Basically, you can get errors at a higher level because consuming objects never knew that consumed objects needed something which wasn't provided.)
Personally I've used a service locator approach a lot (mostly because it's a very handy pattern for introducing DI to a legacy domain as part of a larger refactoring exercise, which is a lot of what I do professionally) and have never run into such issues.
There's yin and yang either way. And I think each solution space has its own balance. If you're finding that direct injection is making the system difficult to maintain, it may be worth investigating service location. Conversely, it may also be worth investigating if the overall domain model itself is inherently coupled and this DI issue is simply a symptom of that coupling and not the cause of it.
Yes, the entire intent of Dependency Injection is that you compose big object graphs up-front. You compose object graphs from the Composition Root, which is a place in your application that has the Single Responsibility of composing object graphs. That's not any particular Controller, but a separate class that composes Controllers with their dependencies.
The Composition Root must have access to all types it needs to compose, unless you want to get into late-binding strategies (which I'll generally advise against, unless there's a specific need).
I am firmly of the opinion that Service Locators are worse than Dependency Injection. They can be a useful legacy technique, and a useful stepping stone on to something better, but if you are designing something new, then steer clear.
The main reason for this is that Service Locators lead to code that has implicit dependencies, and this makes the code less clear and breaks encapsulation. It can also lead to run time errors instead of compile time errors, and Interacting Tests.
Your example uses Constructor Injection, which is usually the most appropriate form of Dependency Injection:
public ViewModelService(ICategoryRepository categoryRepository, IPasswordRepository passwordRepository, IModelValidatorService modelValidator) { ... }
This has explicit dependencies, which is good. It means that you cannot create the object without passing in its dependencies, and if you try to you will get a compile time error rather than a run time one. It also is good for encapsulation, as just by looking at the interface of the class you know what dependencies it needs.
You could do this using service locators as below:
public ViewModelService()
{
var categoryRepository = CategoryRepositoryServiceLocator.Instance;
var passwordRepository = PasswordRepositoryServiceLocator.Instance;
var modelValidator FModelValidatorServiceLocator.Instance;
...
}
This has implicit dependencies, that you cannot tell just by looking at the interface, you must also look at the implementation (this breaks encapsulation). You can also forget to set up one of the Service Locators, which will lead to a run time exception.
In your example I thinky your ViewModelService is good. It references abstractions (ICategoryRepository etc) and doesn't care about how these abstractions are created. The code you use to create the ViewModelService is a bit ugly, and I would recommend using an Inversion of Control container (such as Castle Windsor, StructureMap etc) to help here.
In Castle Windsor, you could do something like the following:
container.Register(Classes.FromAssemblyNamed("Repositories").Pick().WithServiceAllInterfaces());
container.Register(Component.For<IAccountService>().ImplementedBy<AccountService>());
container.Register(Component.For<IApplicationDBContext>().ImplementedBy<IApplicationDBContext>());
container.Register(Component.For<IApplicationSettingsService>().ImplementedBy<IApplicationSettingsService>());
var viewModelService = _container.Resolve<ViewModelService>();
Make sure to read and understand the "Register, Resolve, Release" and "Composition Root" patterns before you start.
Good luck!
Ninject, Sprint.NET, Unity, Autofac, Castle.Windsor are all examples are IoC frameworks that are available. However, I like the learning curve and control of writing my own. It is definitely common practice to not "re-invent the wheel" and just use pre-existing structures. If your comment is along those lines please be gentle.
Can IoC be implemented without the use of XML? It seems to me most, if not all, of the aforementioned frameworks use XML but I would much rather just write mine in C# instead of using XML to load a .dll. The C# is all converted into one .dll eventually anyway.
From my understanding, if wrong please correct, IoC can be used with DI to make the functionality of classes be based off of their definition and implementation while allowing for a separation of concerns.
This is accomplished in C# using microsoft's library System.ComponentModel.IContainer by having a class which inherits it. A class, such as Product, would have an interface IProduct. A generic constructor would then inherit from IContainer and in the constructor, allow a repository to be passed in, an instantiated object to be passed in, and a function to be passed in. This would allow a controller action to then instantiate an interface (IProduct), instantiate the generic constructor with the current repository instance, and then pass it the interface and function.
Is this setup accurate?
I am still trying to learn more about this topic, and have read the wiki articles on IoC, DI, and read about Castle.Windsor, ninject, Unity, and looked over multiple definitions from the MSDN regarding C# libraries which are used. Any assistance, corrections, or suggestions, are greatly appreciated. Thanks
Can IoC be implemented without the use of XML?
Yes, Ninject, Unity, Castle Windsor and Autofac can be configured without using any XML at all. (not sure about Spring.NET, last time I used it it was impossible, version 1.3)
From my understanding, if wrong please correct, IoC can be used with
DI to make the functionality of classes be based off of their
definition and implementation while allowing for a separation of
concerns.
If under "IoC" you mean "IoC container" then yes, it can be used with DI, but since DI is a particular case of Inversion Of Control your IoC container will be just a container for you dependencies. By just having it your will not magically get any DI-friendly types. It's just a support for managing your inverted dependencies.
Edit
As Mystere Man pointed in his answer you need to improve you understanding of the IoC containers. So I would recommend to read this wonderful book (from Mark Seeman) about all that stuff.
I think it is a great exercise to start without a DI container. Before focusing on using a DI framework, focus on best patterns and practices. Especially, design all classes around Dependency Injection and make sure your code follows the SOLID principles. Both sounds pretty easy, but this takes a shift in mindset and a lot of practice before you will get this right (but is well worth it).
When you do this, and do this well, you will quickly notice that your application will evolve in amazing ways. Your code will be testable and extendable in ways that you never imagined before, without your code to rot over time (however, it keeps constant focus to prevent code from rotting).
Still, when you do all this right (which –again- takes a lot of practice), you will still have one part of your application that, despite your best efforts, will get more complex and harder to maintain, as the application grows. This is the part of the application where you wire all dependencies together: the Composition Root.
And this is where DI containers come in. They have fancy names and compete with each other over features, but their goal can be stated in a single sentence:
The goal of a DI container is to keep the Composition Root
maintainable.
Although you can write your own simple DI container to wire up your dependencies, to prevent your Composition Root to become a big fragile, ever changing ball of mud, the container must at least have one crucial feature: Automatic Constructor Injection (a.k.a. auto-wiring). With auto-wiring, the container will look at the constructor arguments of a type that it needs to create, and it will inject the dependencies in it based on the types of those arguments. This feature will make the difference between a maintenance nightmare and a healthy Composition Root. Although creating your own container that supports auto-wiring isn't that hard (with expression trees it takes about 20 lines of code), the moment you start needing auto-wiring is the time to start using one of the existing DI frameworks.
So in conclusion, if you feel it helps you in the learning experience by doing this by hand, please do, as long as you stick to SOLID, DI, DRY, and TDD. When the burden of changing your Composition Root for each change in the application gets too big (which will be sooner than you might expect), switch to an established framework.
I would suggest using an existing DI container first, to understand how it works from the end user perspective. Then you can go about re-designing the wheel. My favorite saying is "You have to know the rules before you can break them".
Some of what you've said doesn't make a lot of sense. you don't have to use System.ComponentModel.IContainer in any framekwork i know of. Maybe Unity requires that (Microsoft's container) but none of the others do. I'm not familiar with Unity thogh.