How would AddScoped() behave outside Asp.net core? - dependency-injection

Let's say I want to use dependency injection in a console application that would run as an Azure web job. Doing so I am reusing my custom service registration method called "AddATonOfServices()" which I use on a related Asp.net application.
My question is, how would the services that are registered in "AddATonOfServices()" using AddScoped() behave now in the console App? are they behaving like Transient or Singleton, or HOW? Would there be any unexpected behavior?
Thanks.

It will be resolved as scoped, if you create a scope via IServiceScopeFactory.
// provider is the root container
using(var scope = provider.GetService<IServiceScopeFactory>().CreateScope())
{
var scopedService = scope.ServiceProvider.GetRequiredService<IScopedService>();
// do something
}
// scope will be disposed and all scoped and transient services which implement IDisposable
If you resolve a scoped service from the root container, then it will be effectively a singleton (assuming provider lives as long as the application does)

Related

Autofac: What is the difference between InstancePerRequest and InstancePerLifetimeScope in an MVC app

I am trying to understand lifetime scopes in Autofac IOC and have the following question.
Assume we have class:
public class TestMemLeak
{
SomeDisposableContext cn;
public TestMemLeak(SomeDisposableContext context)
{
cn = context;
}
}
where the injected dependency SomeDisposableContext implements IDisposable.
In an MVC application I get a memory leak when resolving TestMemLeak object if SomeDisposableContext is registered as InstancePerDependency (default option). The leak is gone if I register it as InstancePerRequest or InstancePerLifetimeScope.
I don't understand why InstancePerLifetimeScope fixes the leak. My understanding is that if we resolve dependency from root then InstancePerLifetimeScope should behave in same way as InstancePerDependency, and the solution to problem would be to pass ILifetimeScope to TestMemLeak class and resolve the dependency using lifetime scope. Why is this assumption wrong and what is the difference between InstancePerRequest and InstancePerLifetimeScope in MVC app scenario (apart from InstancePerRequest looks for specific 'httpRequest' lifetime scope)? When should I use InstancePerRequest? It would be great if someone could explain this especially from memory leaks perspective.
As described in the documentation, InstancePerLifetimeScope works for nested resolves. So it means that in your case one object was instantiated for your HTTP request and it gets its dependencies injected and they are all resolved within the same scope. This is basically done by Autofac MVC integration, it is known as BeginLifetimeScope with the HTTP scope tag.
In case your dependency will be instantiated somewhere else, not within the nested resolution three, it will be outside of the lifetime scope and will not be disposed.
InstancePerRequest however is nothing more than the InstancePerMatchingLifetimeScope with predefined tag constant MatchingScopeLifetimeTags.RequestLifetimeScopeTag. Therefore, your dependency does not need to be instantiated inside the nested lifetime scope resolution, it will be enough for the scope with this tag to be open to get the instance attached to this scope.

asp.net 5 DI: Using scoped service outside request

We have a IOrderManager service which uses some other services registered in DI via AddScoped().
Now we need to use that service in the OnMessage handler for some queue which, obviously, is raised outside any request pipeline.
So when we try to get our service using something like
var orderManager = ServiceProvider.GetRequiredService<IOrderManager>();
we got "Can't access disposed object ..." exception.
Question: is it possible to "tell" DI that we are inside some "fake request" processing to avoid disposing services registered as "scoped"?
If your IOrderManager is outside request scope, you can create your custom scope per-message like this:
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var myService = serviceScope.ServiceProvider.GetRequiredService<MyService>();
}
If you're using scoped services within IOrderManager, IOrderManager needs to also be scoped.
If you don't do this, when the IOrderManager instance is first created, it will "capture" the scoped dependencies from the current request.
Any future usage of IOrderManager will continue to use the old scoped dependencies and not dependencies from the current request scope.
Next, the only reason you should use scoped dependencies is if they somehow maintain state across a single request and need to isolate that state from other requests.
If your IOrderManager doesn't actually need information that is scoped to a request, it shouldn't be scoped and shouldn't use dependencies that are also scoped.
Put another way, if you think it should be usable outside of an active request, it by definition is not scoped does not require scoped dependencies.

MVC Dependency resolver conditional

I am using dependency resolver and i have added my unity container to the same. So by default "GoldCustomer" gets injected in to the "CustomerController" as per the current container rules.
IUnityContainer oContainer = new UnityContainer();
oContainer.RegisterType<ICustomer, GoldCustomer>(); // injects GoldCustomer
DependencyResolver.SetResolver(new UnityDependencyResolver(oContainer));
If i want to change by current container configuration i can always create new Container and set it and call the SetResolver again. I know that the above code should be configurable via XML config but still if we need to pickup new container objects we have to still call the setresolver.
Is this the right way or are there better ways of changing container depedency rules while the application running.
Second what are the events where we can change the container is it session_start , httphandler's or something better.
Firstly why would you need multiple containers? It must be the singleton object who keeps all the dependency registered since the application started.
In a practice I would say keep single container and if required create multiple Registration function in separate assemblies and invoke all of them in a AppBootstrapper.
If it's an application then best way is to use the Application start with Async behaviour so that the startup doesn't get affected.
======================================================
Unfortunately the Named registration is the only option and Unity required to register with names explicitly. Thats why I personally like DI containers like Autofac and SimpleInjector. They are fast and They allow multiple registrations of an Interface with multiple Types and the resolver uses Type resolver and Named resolver methods without explicitly asking for Names and those resolvers are overridable too.
I am not sure why it does not look that complex to me , If I understand question quickly I can do it as follows,
assume that I have interface IMovieRepository and two classes implementing it EnglishMovieRepository and HindiMovieRepository.
How about resolving them as in UnityConfig.cs as follows,
If(condition)
{
container.RegisterType<IMovieRepository, EnglishMovieRepository>();
}
else
{
container.RegisterType<IMovieRepository, HindiMovieRepository>();
}
If requirement is something different then please let me know
Thanks
/dj

Inject with different scope when using DbContext with custom resource provider

In an application I have the following components (among others):
MyDbContext : Entity framework data access
DBResourceProviderFactory : A custom ResourceProviderFactory providing a custom IResourceProvider (called DBResourceProvider...)
Other services
StructureMap
The custom resource provider is looking resources up in the db using MyDbContext, injected similarly as described in this SO answer.
The MyDbContext is also used in various other services, and since it is a web application, I use StructureMaps HttpContextScoped method to limit the lifetime of MyDbContext to the lifetime of the request (see an other SO question and its answer on this subject):
x.For<MyDbContext>().HttpContextScoped();
However, it seems that the lifetime of an IResourceProvider is not limited to a single http request. Therefore, DBResourceProvider keeps hanging onto a MyDbContext reference which will be disposed after the first request.
How can I handle this lifetime mismatch - have StructureMap return a transient MyDbContext for IDbResourceProvider while returning HttpContext-scoped instances to all other services?
Do I need two different implementations to do that? A marker interface?
Or is it a bad idea to use Entity Framework to look up localized resources in the first place (performance etc.)?
If you have a service that has (or needs to have) a long lifetime than (one of) its dependencies, the general solution is to use a factory to get those dependencies.
In your situation the solution might be simple. When your DBResourceProvider is defined in your composition root of your MVC application, it would simply succeed to use the DependencyResolver.Current.GetService method to get the MyDbContext.
When the DBResourceProvider service isn't part of the composition root (for instance because it contains business logic that you need to test), you could either extract that logic into its own class, to allow the service to be in the composition root, or you can inject a (singleton) factory (for instance IDbContextFactory or Func<MyDbContext>) that allows you to get the proper instance to be resolved.

DI: Register-Resolve-Release when using child containers

There's this software, X, which has this really complicated API that I have to write a facade for. I wrote a class library, XClientLibrary, and I made it using DI and IoC container (Unity). This was possible because my library exports services (interfaces) so users are not aware of the concrete classes which use constructor DI. They're also unaware of the IoC container.
The "root service" is a IXClient instance which is supposed to be created once and used as long as the application runs. (It is a desktop application btw). The X-client allows users to connect to X-hosts if they know the URL. A X-host allows users to access host's services and their services and so on (quite a complex object graph). This is sample user code:
// 1. app startup
XClientProvider provider = new XClientProvider(); // call only once per app
IXClient xClient = provider.GetClient(); // always returns the same instance
xClient.Startup();
// 2. app normal usage
IXHost host = xClient.ConnectToHost(new Uri("http://localhost")); // return new instance each time
IXService1 service = host.GetThis();
IXService2 otherService = service.DoThat();
...
host.Dispose();
// get another host, consume it, dispose it, etc
...
// 3. app shutdown
xClient.Shutdown();
provider.Dispose();
I tried to follow Mark Seemann's suggestions to implement this, but I'm not sure if they apply to a class library too. The client provider is the composition root, which is the only place where the IoC container is used. The composition root follows the RRR pattern:
the container is created on new XClientProvider() and configured
the container resolves IXClient when calling GetClient()
the container is disposed on provider.Dispose()
Things get complicated when the container is asked to resolve IXHost. Its implementation is:
internal class XHost : IXHost
public XHost(Uri uri, IXService1 service1)
The client is supposed to create XHost instances, so its implementation needs to know how to create IXService1:
internal class XClient : IXClient
public XClient(Func<IXService1> xService1DelegateFactory)
Invoking the delegate factory reaches the container which creates a IXService1. Also, let's say that in this graph there is a class XComponent7 which requires the exact IXService1 instance which was used to create the host:
internal class XComponent7 : IXService7
public XComponent7(Func<IXService1> service1DelegateFactory)
I have to use Func to deal with the circular dependency. The container should be configured such that once a IXService1 was resolved, it will provide the same instance whenever asked to resolve IXService1.
Now it gets really complicated. I want to restrict this behavior "per host resolve", meaning once a host is created the container should create a IXService1 and cache it and provide it to whatever component needs it, as long as the component is part of the object graph of the host. I also need a way to dispose all components when a host is disposed.
I was thinking I can do it using child containers. I can create one when users call ConnectToHost, ask it to resolve the host and dispose it on host disposal. The main container is still alive and won't be disposed until they call Dispose on the provider.
Problem is, I think it breaks the RRR pattern. So I wonder how RRR works when child container are involved... Maybe the IXHost is another "root" which can be directly resolved by the composition root? Or maybe there's a really smart Unity lifetime manager which can do what I need?
#Suiden So my understanding is: Your client is something that lets you lookup hosts (like a registry). Hosts offer services implemented by components. Every application has exactly one instance of your lookup/client. Your components not only implement services but might need other services to do their job. You want to resolve all parts of that object graph exactly once and when you dispose your client throw all of it away.
A couple of thoughts:
Circular references between dependencies (or services) is something you should try to avoid. If these services need each other that indicates they should be one service. That's what high cohesion, low coupling is about.
Unity does not clean up after itself. That means that even if you dispose a container that will not dispose the objects created by that container. The cleanup feature is on the wish list for Unity vNext
If you want to resolve an instance of some service and cache that instance inside your client/host wherever you should have a look at Lazy. It takes a Func to create an instance of T and evaluates that Func the first time the value is requested. So you can inject the Func into your classes or teach Unity to inject Lazy instances directly.
Child containers are a feature I find less than usefull. You can scope registration information and object lifetimes. But to make use of these scopes you would have to reference the appropriate child container. That means you are dropping dependency injection in favor of the ServiceLocator anti-pattern.

Resources