I am using Autofac to handle dependency injection in my application. In order not to have to do every single registration explicitly, I first use RegisterAssemblyTypes().AsImplementedInterfaces() and then only take care of those that need to be specially configured.
I have an interface called IToolStripPopulator that has a few different implementations, several of which are in use, but some aren't anymore (as I'm trying to work SOLIDly and adhere to OCP, I am usually not changing them if I need different functionality, but rather leave them alone and create new ones that do what I need now). For that reason I need to overwrite the automatic registration for the interface, in two ways:
One implementation is to be injected into my main logic and acts as a decorator for a few of the others. I naturally want this to be registered via As<IToolStripPopulator>() and be done with it as this is the implementation my application's functionality currently depends on.
Those other implementations are the "inner" populators only to be used within that decorator class. To inject them, there are two ways:
Explicitly wiring up the constructor for the outer implementation with the specific types; this is not very nice, also because that constructor would have to take the exact number of inner populators I am using right now, which is not OCP compliant.
Have the outer implementation take an IEnumerable<IToolStripPopulator>; this is what I'd like to do, but it's also where I'm stuck.
I can't let Autofac resolve that IEnumerable on its own, because it would just resolve all implementations of the interface, even those that I'm not using anymore as well as the "outer" that I don't want in there (and which would probably cause an endless loop during resolution).
So what I'd like to do is this:
// the inner populators
builder.RegisterType<BrowsersMenuPopulator>().Named<IToolStripPopulator>("inner");
builder.RegisterType<ThreadsafeConnectionMenuPopulator>().Named<IToolStripPopulator>("inner");
// the decorator implementation
builder.RegisterType<BrowserAndConnectionMenuPopulator>().As<IToolStripPopulator>().WithParameter( ? );
But there is no way to actually access the existing registrations at that point.
....and here I tried just one more thing which I didn't actually expect to work, but it did.
builder.Register(c => c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner")).As<IEnumerable<IToolStripPopulator>>();
does not, as I would have expected, try to resolve an IEnumerable<IToolStripPopulator> registration named "inner", but an IEnumerable of IToolStripPopulator registrations named "inner" - exactly as I need it.
This will then correctly be resolved and injected into the decorator implementation just from having that registered As<IToolStripPopulator>() with no further configuration.
From a formal aspect I would actually have preferred being able to state the name by which to resolve directly with the decorator registration because that would be more intuitive and flexible (what if I need to resolve several IEnumerable<IToolStripPopulator>?), but in many cases this should be enough.
#codinghorror's concept of "rubber duck problem solving" rules my every workday....
The only way to directly specify that I know of is to "new-up" directly in your registration code:
//decorator impl
builder.Register(c => new BrowserAndConnectionMenuPopulator(c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner"),...)).As<IToolStripPopulator>();
This has the advantage of specifying directly in the registration the exact required dependencies, but the disadvatage of loss of flexibility in reconfiguring BrowserAndConnectionMenuPopulator's dependencies. I included this for completeness, but honestly I prefer the solution you discovered.
Related
I'm trying to learn asp.net core (3.1) and clean architecture at the same time. The GitHub repository which I'm using as base is the https://github.com/ivanpaulovich/clean-architecture-manga and it's great.
The approaches used are pretty good and the repo owner answers you about the reasons of each approach.
The problem I found is not about the approach now, but a better resolution.
The webapi\dependencyinjection\ApplicationExtensions.cs class adds a scope for every use case he has:
services.AddScoped<Application.Boundaries.CloseAccount.IUseCase, Application.UseCases.CloseAccount>();
services.AddScoped<Application.Boundaries.Deposit.IUseCase, Application.UseCases.Deposit>();
services.AddScoped<Application.Boundaries.GetAccountDetails.IUseCase, Application.UseCases.GetAccountDetails>();
services.AddScoped<Application.Boundaries.GetCustomerDetails.IUseCase, Application.UseCases.GetCustomerDetails>();
services.AddScoped<Application.Boundaries.Register.IUseCase, Application.UseCases.Register>();
services.AddScoped<Application.Boundaries.Withdraw.IUseCase, Application.UseCases.Withdraw>();
services.AddScoped<Application.Boundaries.Transfer.IUseCase, Application.UseCases.Transfer>();
There is any way to make it generic? To resolve the sample code with one line code only and all the use cases created after it will be injected?
Explicitly registering dependencies can be seen as a benefit because you won’t get unwanted surprises later at runtime from seemingly “magic” registrations. This is especially true since your convention to register these types appears to be solely based on interface naming or namespaces. I would recommend you to add some stronger identifiers (e.g. common interfaces, or marker interfaces) if you want to utilize a convention-based registration there. Otherwise, it may seem better to list every single DI registration even if that may seem very verbose.
That being said, there are utilities that will help you with convention-based registrations. Of course, you could always write some code using reflection to register such things automatically. There is also this very useful utility package Scrutor that will register types based on conventions for you.
If each of the type only implements a single interface, then you could use the following scan to register the services as scoped services for their interfaces:
var type = typeof(Application.UseCases.CloseAccount);
services.Scan(scan => scan.FromAssembliesOf(type)
.AddClasses(classes => classes.InExactNamespaceOf(type))
.AsImplementedInterfaces()
.WithScopedLifetime());
I would like to register a singleton component for multiple services and define which constructor to use, depending on which service was used during the resolve call.
I tried this:
_builder.RegisterType<TComponent>()
.As<IService1>()
.FindConstructorsWith(ConstructorFinder1)
.SingleInstance();
_builder.RegisterType<TComponent>()
.As<IService2>()
.FindConstructorsWith(ConstructorFinder2)
.SingleInstance();
But this leads to two different "singleton" instances, depending on which service was used.
So I tried:
_builder.RegisterType<TComponent>()
.As<IService1>()
.FindConstructorsWith(ConstructorFinder1)
.As<IService2>()
.FindConstructorsWith(ConstructorFinder2)
.SingleInstance();
This solves the singleton issue, but sadly the second FindConstructorsWith call overrides the first call, i.e. for both services ConstructorFinder2 is used.
I had assumed (hoped) that the ConstructorFinders would be stored with respect to the service, but apparently this is not the case.
Is what I'm trying to achieve conceptually wrong, does Autofac not support it or am I simply missing something?
EDIT:
Once again thanks to Travis for his great response. Apparently I left out a few details that made things confusing. Let me add some now.
This question was actually a kind of follow-up to How to determine which constructor Autofac uses when resolving (where Travis also helped me along). So the issue comes up when deserializing and it affects many different objects.
I get the arguments about composition, seperation of concerns and how having several ctors is often considered a code smell, but in the context of deserialization (at least for the app I'm currently developing) it is extremely useful to be able to create instances differently, depending on if they are newly built or deserialized from a project file. Several members that need to be initialized when building a new instance do not have to be initialized when deserializing (because their values would be overridden during deserialization anyway). It would mean extra performance costs and (and, in this case) cause other issues regarding the throw-away-initializations.
After spending days trying to find a solution (with complications also coming from the Newtonsoft Json side) I've decided to discontinue Autofac and implement our own IOC container. For general purposes it cannot (obviously!) compete with Autofac in any way, but since we were really only using a small subset of Autofac's great features, I felt we could try to roll our own. It took me a lot less than the days I've spent on trying to wrap my head around a monolithic black box. Yes, Autofac is open source, but stepping through the code no walk in the park.
First tests are very promising and it feels good to regain full control of such a vital component of the application.
Again, the reason for leaving Autofac was that it is not (feasibly) possible to define how a singleton component is constructed depending on the service it was constructed for. And from a general structure/concept point-of-view I understand that it makes sense to strictly seperate the service and the construction-how-tos. But during deserializing things are different, I believe. And, now that I'm independent of Autofac, I may decide to alter the mechanisms so they fit into the overall concept in a more straight-forward way.
This is sort of a difficult question to answer because it seems you have some underlying goal you're trying to achieve and you have a solution you want to work but perhaps it's the wrong solution and you should ask a [new] question depending on how this response works out for you.
Let me walk this through to see if I can explain why it's hard to answer.
I would like to register a singleton component for multiple services and define which constructor to use, depending on which service was used during the resolve call.
If it's a singleton that means there's one in the whole system, right? It'll be effectively "first in wins." If something resolves it as an IService1 then the constructor associated with that will be called and even if you try resolving it as IService2 later no construction will happen because the singleton was created. The converse is also true - IService2 gets resolved and the constructor path is followed there, then things asking for IService1 will get the singleton and no constructor is called.
That raises a concern:
If you know which thing, for sure, will be resolving first, then why do you need two different constructor selectors?
If you don't know which thing will be resolving first, then are you accounting for the system unpredictability?
I have seen these sorts of questions before and usually what they indicate is one of two things:
You are trying to do some sort of selection or special logic based on context. There's an Autofac FAQ about this that may help. Usually the way around this is to refactor. I'll get back to that in a second.
You are trying to "share registrations" between two different applications. The answer to this is to use Autofac modules and reuse those; but if there are special registrations for each app type, let that happen.
This isn't to say that either of these are what you're asking for, but this is where I've seen such questions. Usually there's some unspoken goal where a solution has been pre-chosen and it's better ask how to solve the goal rather than how to implement a very specific solution. Again, I could be wrong.
On the refactoring note for item 1, above, I can further guess based on the desire for a singleton that there's some sort of resource like a database connection that needs to be shared or is expensive to spin up. Consider splitting the TComponent into three separate classes:
TCommonExpensiveComponent - this is the stuff that is actually expensive to spin up and really does need to be a singleton, but does not differ across IService1 and IService2.
TService1 - implement IService1 with only the required constructor so you don't need a constructor finder. Have it consume TCommonExpensiveComponent.
TService2 - implement IService2 with only the required constructor so you don't need a constructor finder. Have it consume TCommonExpensiveComponent.
The idea being avoid the complexity of registrations, keep the shared/singleton that you want, and still get different constructor usage as needed. You may want to throw in some common base/abstract class, too, that the TService classes can derive from if there's really a lot of common logic.
Is what I'm trying to achieve conceptually wrong, does Autofac not support it or am I simply missing something?
Technically you could do some really crazy stuff in Autofac if you wanted to, like write a custom registration source that waits for someone to query for the IService1 or IService2 registration and then picks a constructor based on that, dynamically serving the registration as needed. But, truly, don't even start down this road.
Instead, it would be good to clarify what the problem is that you're trying to solve and how you plan on working around the challenges listed above if my response here doesn't help. Do that in a brand new question that goes into more detail about your challenge and what you've tried. This not being a forum, having a conversation to try and weed out additional help given the current question really isn't feasible. Plus, taking a second to step back and maybe reframe the question sounds like it might help here.
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 building a MVC application with Autofac and EntityFramework. I have a large set of data repositories / business objects that use my logging interface (NLog). I have just started working with Autofac and would like to know the preferred way for property injection:
Pass ILogging as constructor property, for this I have to set each local property from the constructor and creates larger constructor footprints.
Register each object individually with Autofac (they do not share a generic interface)
Use an Autofac.Module to locate these objects and set the property with reflection
Create a generic interface ILoggerDependency and register this with Autofac, this way all objects are easely registred.
My preferred method (out of lazyness...) is to have a generic interface that I can register with Autofac.
I am not that familiar with Autofac, so I'll try to give you my best recommendation based on what I know.
If there is one thing a lot of people gets wrong with dependency injection, it has to be using it for automation. The goal of DI is not to remove magic from your code. If anything, it is quite the opposite.
Keeping that in mind, I would not even consider using reflection as it hides large amounts of fragile plumbing.
Next, interfaces in OOP are meant to express what an object can do. Being injected is definitely not an action an object can take, but rather something that is imposed on an object. Even though, it is a quick and dirty way to solve your issue, I would refrain from using it as it will denature the structure of your code.
I have trouble understanding what you mean by pass ILogging as constructor property. Basically, you mean to resolve the interface yourself in the constructor? This looks a lot like property injection which defeats the purpose of DI by adding a strong dependency on your container within your class. Basically, instead of depending on Log4Net, you end up depending on Autofac. To fix this, you would need to add a service locator and then you still end up with a similar problem. How do you inject your service locator?
This is why I would register each object individually. It lets your container do its job. It doesn't affect your code structure and abstractions. It doesn't uses reflection (magic). It doesn't force you to depend on your container within each class. Besides, it also gives you a centralized place to look for when adding or removing repositories from your code.
I've long considered it a bad practice to call out to a classes dependencies from within the constructor but wasn't able to articulate why to a colleague yesterday. Can anyone provide a good reason for NOT doing this?
There are several reasons for Nikola Malovic's 4th law of IoC:
When we compose applications with Constructor Injection we often create substantial object graphs, and we want to be able to create these graphs as efficiently as possible. This is Nikola's original argument.
In the odd (and not recommended) cases where you have circular dependencies, the injected dependencies may not yet be fully initialized, so an attempt to invoke their members at that time may result in an exception. This issue is similar to the issue of invoking virtual members from the constructor. Conceptually, an injected dependency is equivalent to a virtual member.
With Constructor Injection, the constructor's responsibility is to demand and receive the dependencies. Thus, according to the Single Responsibility Principle (SRP), it should not try to do something else as well. Some readers might argue that I'm misusing the SRP here, but I think I'm simply applying the underlying principle in a more granular context.
Please notice that this rule is contextual: it applies to Services that use Constructor Injection. Entities and Value Objects tend not to use DI, so their constructors are covered by other rules.
If you call out to your dependencies, you're actually doing work in a constructor.
From a client's perspective that is unexpected. When I do something like this:
var myObj = new SomeClass();
I don't expect any side-effects.
If you do things in the constructor, for example it could throw an exception, which is certainly not what you expect. It's like naming a method FetchUsers and inside that method creating a user and returning it. Not what you'd expect.