A would like to make my ASP.NET Core project could see only another library: Api, where I have interfaces. And another library makes wiring for interfaces and their implementation.
Instead of it Microsoft Dependency Injection Library proposes to make a wiring point right in the asp.net project. In this case this project will see both libraries: Api and ApiImpl. And it's not acceptable.
I wanna find a solution like Ninject, for example, does with modules.
A kind solution of this is here:
https://github.com/aspnet/DependencyInjection/issues/497
Related
What is the correct way for a Libary to call an object that was injected through Dependency Inject?
Background: I have multiple .NET Core app that uses dependency injection for all major objects and uses libraries for reusability. It is working great. App1 calls Libary1 and Libary2. App2 calls Libary2 and Libary3 etc.
service.AddTransient<Libary1.ILibary1Dependency, Libary1.Libary1Dependency>();
service.AddTransient<Libary2.ILibary1Dependency, Libary2.Libary1Dependency>();
service.AddTransient<Libary2.ILibary2Dependency, Libary2.Libary2Dependency>();
service.AddTransient<Libary3.ILibary1Dependency, Libary3.Libary1Dependency>();
Now in Libary2.ILibary1Dependency there is a method that needs to call a new Libary2.ILibary2Dependency. What is the best way to do this?
Should I just do a new Libary2.ILibary2Dependency(property1, property2...);?
Is it ok in the main app to actually inject the IServiceCollection object and then in the constructor of the Libary2.ILibary1Dependency get the IServiceCollection?
Is there some nugget package that I don't know about that fixes this perfectly?
Note: Libary2.ILibary2Dependency does get called on its own via dependency injection, if you were wondering
As suggested in the comments, keep the libraries independent of the Service Dependency Injection. And let the Caller make the decision to inject them on need basis and it helps to keep the libraries independent of IOC Framework.
If you need to change the IOC Framework or even upgrade to latest versions, you probably need to spend time to update across the libraries, the more these dependencies you have the more house cleaning needed eventually.
I have seen people creating generic wrappers to avoid having specific dependencies on IOC Frameworks, but its kind of overkill.
If all you have is a 3 or 4 projects, it doesn't matter to refactor them away in both directions.
In .NET framework, you can use Ninject to achieve contextual binding.
So for example:
Bind<IWarrior>().To<Samurai>().WhenInjectedInto(typeof(OnLandAttack));
Bind<IWarrior>().To<SpecialNinja>().WhenInjectedInto(typeof(AmphibiousAttack));
This means you can inject different concrete implementations depending on what you're injecting into.
I cannot see any method to achieve the same thing in .NET Core 2.2 - is this not possible, or does it just require a bunch of extra configuration?
Example code from the Ninject site
I had a need for something like this and ended up creating a NuGet package for it: https://www.nuget.org/packages/ServiceProviderContextualBinding/
Usage looks like this:
services.AddSingleton<IService, DefaultService>();
services.AddSingleton<ReplacementService>();
services.WithReplacement<IService, ReplacementService>()
.AddSingleton<Consumer>();
This package is basically a facade over the ActivatorUtilities.CreateInstance method, which is part of the MS DI code.
Why is the reason the IDependencyResolver is coupled with the System.Web assembly (either Mvc or Http) in the .NET framework ?
The goal of a DI system isn't that it should provide an agnostic way of serving dependencies to a customer ? What if I want to use IDependencyResolver in a project that should not reference anything related to System.Web ?
Edit:
This is more a philosophical question than a request about how to do, because I know there are other alternatives such as open source DI library.
The goal of a DI system isn't that it should provide an agnostic way of serving dependencies to a customer ?
That is correct, but in this case, IDependencyResolver is specific to the library where it is defined. It is that library's DI abstraction to allow an agnostic extensibitliy point for dependency resolution. And I believe that that was the initial goal of the abstraction.
It was not really made to be reused independently by other libraries, which is evident in that there are two versions for both MVC and Web API. Though they share the same name and have the same purpose, their implementations differ slightly.
It also demonstrates the Conforming Container anti-pattern as mentioned in this article by Mark Seemann, where the article also mentions the above abstractions as known examples of Conforming Containers for .NET. Even my preferred approach of using IServiceProvider made the list.
What if I want to use IDependencyResolver in a project that should
not reference anything related to System.Web ?
My suggestion then would be to not use IDependencyResolver from System.Web. I would also add that above all, particular attention should be payed to following proper design patterns, making sure that one has an understanding of the concepts and where they should be applied or avoided.
The interface IDependencyResolver is an extension point of the System.Web-frameworks. The frameworks rely on this interface to resolve instances (of controllers and their like) and their dependencies.
The framework has its own implementation of the interface, but you can provide your own implementation of this interface. The Built-in implementation has a limited functionality (external configuration, injection types, interception).
Most IOC-Container and DI-Frameworks provide an implementation of this interface, so that you can integrate them into the existing framework.
Why is the reason the IDependencyResolver is coupled with the
System.Web assembly (either Mvc or Http) in the .NET framework ?
Because it is an interface 'they' use to resolve framework services. But yeah... they should, for the very least, have used IServiceProvider from System namespace.
The goal of a DI system isn't that it should provide an agnostic way of
serving dependencies to a customer ?
Nope. That is not the goal in that context. The main goal for framework author is to let you extend or even replace internal services framework is using.
In your code you should introduce your own facades over these 'standard' interfaces. They are very weak abstractions - good for base, but very far away from any richer resolving or lifetime management strategies.
What if I want to use IDependencyResolver in a project that should not
reference anything related to System.Web ?
You cannot (without adding System.Web reference) and you shouldn't. Use your own internal abstraction(Facade) over DI framework. Just like you shouldn't use NLog.ILogger directly in your classes, same applies to DI framework abstractions.
Some frameworks will make it close to or just impossible to do but you should use your own Facades wherever possible.
Same rules apply in broader sense as well.
Don't attach your project (unnecessarily) to some cloud service such as Azure. Other side might have much better prices some day. Limit dependencies and sticky parts as much as possible.
Edit:
This is more a philosophical question than a request about how to do,
because I know there are other alternatives such as open source DI library.
Oh... and same advice go with DI frameworks. Don't overuse DI framework features that could be easily implemented in different way over your Facades.
NOTE: Same goes with: CI pipelines, Service Bus/Message Queue frameworks.
I am looking to do the equivalent of this:
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
But in a console application. I also have cases where I need to do this in a worker role. I don't want to have to add a reference to the MVC dll all over the place. I am wondering if there is an equivalent for non-mvc projects? I need to stash the container I create so I can access it throughout my application. I thought of creating a static variable, but I'd rather not do this.
I saw there is a CommonSerivceLocator nuget for Simple Injector but oddly it requires 2.8.1 and the latest non-mvc Simple Injector is 2.8.0.
I don't want to have to add a reference to the MVC dll all over the place.
This indicates that you are not applying dependency injection but are doing Service Location, which is an anti-pattern.
If you apply constructor injection to all your components, you will be able to let Simple Injector build up a complete object graph of dependent components (of many levels deep) without any of your components to know about the existence of an IoC container such as Simple Injector or an IoC abstraction such as the Common Service Locator and MVC's IDependencyResolver. This prevents you from referencing your IoC container or such abstraction "all over the place".
So in a Console Application that means that you typically have one place where you resolve the object graph(s). This is the place in the application that already knows about the existence of the IoC container. This place is typically referred to as the Composition Root.
I saw there is a CommonSerivceLocator nuget for Simple Injector but oddly it requires 2.8.1 and the latest non-mvc Simple Injector is 2.8.0.
I seem to have made an error in the build scripts that create the NuGet packages and although NuGet usually applies checks when a package is uploaded, for some reason it failed to check this. I fixed this and pushed v2.8.2 of the CommonServiceLocator adapter to NuGet. But note that we are dropping support for the CSL adapter in v3 of Simple Injector because it leads to bad practice. Don't use it; you don't need it.
I recently used Dependency Injection pattern with Autofac as the IoC Container.
Normally, I would use it inside core application (Winform, WCF, WPF etc).
Currently I'm learning to create a class library project as a framework for my peer developers, and I tend to stick with the DI pattern since it allows me to unit test as I go.
How do I configure the IoC Container in a class library project without an entry point?
Should I just make something like :
public static void ConfigureLibrary() {
//.. Do bootstraping here
}
and let core application to call it when the core app start?
How did libraries like the Patterns & Practices Enterprise Library or Spring.Net configured?
How did libraries like the Patterns & Practices Enterprise Library or
Spring.Net configured?
Here is an interesting article from Chris Tavares about the subject.
How do I configure the IoC Container in a class library project without an entry point?
Generally the application should be the root for your service registrations. But yes, one may provide default-registrations in a library. Here is a blog-post I did some days ago how I and my team currently do.