How do I prevent Structuremap nested container from disposing an instance - structuremap

I'm using a "nested container per request" pattern. It's wrapped in a using block so the nested container is disposed after handling the request. This causes all instances created by the nested container to also be disposed at the end of the request.
This works great and is usually exactly what I want to happen. However I have ran into a use case where I don't want one particular instance to be disposed while everything else is.
I tried explicitly removing the instance at the bottom of the using block like so:
using (var nestedContainer = _container.GetNestedContainer())
{
nestedContainer.Configure ( x =>
x.For<IFoo>()
.Use(getFooForRequest())
);
var handler = (IRequestHandler) nestedContainer.GetInstance(handlerType);
handler.execute(....)
nestedContainer.EjectAllInstancesOf<IFoo>();
}
Unfortunately it appears that EjectAllInstancesOf is also calling dispose.
My application has a few different instances of IFoo, and they all need to live for the entire lifetime of the application. However incoming requests need to be dynamically associated with one particular instance of IFoo.
Injecting it into the nested container like above accomplished this goal, but my IFoo is getting disposed with the nested container, which is bad.
So how do I block the dispose for IFoo while still letting it dispose everything else?
If that's not possible, is there some other way to dynamically select my per-request IFoo without manual injection via nested.Configure()?

Related

Dependency Injection and/vs Global Singleton

I am new to dependency injection pattern. I love the idea, but struggle to apply it to my case. I have a singleton object, let’s call it X, which I need often in many parts of my program, in many different classes, sometimes deep in the call stack. Usually I would implement this as a globally available singleton. How is this implemented within the DI pattern, specifically with .NET Core DI container? I understand I need to register X with the DI container as a singleton, but how then I get access to it? DI will instantiate classes with constructors which will take reference to X, that’s great – but I need X deep within the call hierarchy, within my own objects which .NET Core or DI container know nothing about, in objects that were created using new rather than instantiated by the DI container.
I guess my question is – how does global singleton pattern aligns/implemented by/replaced by/avoided with the DI pattern?
Well, "new is glue" (Link). That means if you have new'ed an instance, it is glued to your implementation. You cannot easily exchange it with a different implementation, for example a mock for testing. Like gluing together Lego bricks.
I you want to use proper dependency injection (using a container/framework or not) you need to structure your program in a way that you don't glue your components together, but instead inject them.
Every class is basically at hierarchy level 1 then. You need an instance of your logger? You inject it. You need an instance of a class that needs a logger? You inject it. You want to test your logging mechanism? Easy, you just inject something that conforms to your logger interface that logs into a list and the at the end of your test you can check your list and see if all the required logs are there. That is something you can automate (in contrast to using your normal logging mechanism and checking the logfiles by hand).
That means in the end, you don't really have a hierarchy, because every class you have just gets their dependencies injected and it will be the container/framework or your controlling code that determines what that means for the order of instantiation of objects.
As far as design patterns go, allow me an observation: even now, you don't need a singleton. Right now in your program, it would work if you had a plain global variable. But I guess you read that global variables are "bad". And design patterns are "good". And since you need a global variable and singleton delivers a global variable, why use the "bad", when you can use the "good" right? Well, the problem is, even with a singleton, the global variable is bad. It's a drawback of the pattern, a toad you have to swallow for the singleton logic to work. In your case, you don't need the singleton logic, but you like the taste of toads. So you created a singleton. Don't do that with design patterns. Read them very carefully and make sure you use them for the intended purpose, not because you like their side-effects or because it feels good to use a design pattern.
Just an idea and maybe I need your thought:
public static class DependencyResolver
{
public static Func<IServiceProvider> GetServiceProvider;
}
Then in Startup:
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
{
DependencyResolver.GetServiceProvider = () => { return serviceProvider; };
}
And now in any deed class:
DependencyResolver.GetServiceProvider().GetService<IService>();
Here's a simplified example of how this would work without a singleton.
This example assumes that your project is built in the following way:
the entry point is main
main creates an instance of class GuiCreator, then calls the method createAndRunGUI()
everything else is handled by that method
So your simplified code looks like this:
// main
// ... (boilerplate)
container = new Container();
gui = new GuiCreator(container.getDatabase(), container.getLogger(), container.getOtherDependency());
gui.createAndRunGUI();
// ... (boilerplate)
// GuiCreator
public class GuiCreator {
private IDatabase db;
private ILogger log;
private IOtherDependency other;
public GuiCreator(IDatabase newdb, ILogger newlog, IOtherDependency newother) {
db = newdb;
log = newlog;
other = newother;
}
public void createAndRunGUI() {
// do stuff
}
}
The Container class is where you actually define which implementations will be used, while the GuiCreator contructor takes interfaces as arguments. Now let's say the implementation of ILogger you choose has itself a dependency, defined by an interface its contructor takes as argument. The Container knows this and resolves it accordingly by instantiating the Logger as new LoggerImplementation(getLoggerDependency());. This goes on for the entire dependency chain.
So in essence:
All classes keep instances of interfaces they depend upon as members.
These members are set in the respective constructor.
The entire dependency chain is thus resolved when the first object is instantiated. Note that there might/should be some lazy loading involved here.
The only places where the container's methods are accessed to create instances are in main and inside the container itself:
Any class used in main receives its dependencies from main's container instance.
Any class not used in main, but rather used only as a dependency, is instantiated by the container and receives its dependencies from within there.
Any class used neither in main nor indirectly as a dependency somewhere below the classes used in main will obviously never be instantiated.
Thus, no class actually needs a reference to the container. In fact, no class needs to know there even is a container in your project. All they know is which interfaces they personally need.
The Container can either be provided by some third party library/framework or you can code it yourself. Typically, it will use some configuration file to determine which implementations are actually supposed to be used for the various interfaces. Third party containers will usually perform some sort of code analysis supported by annotations to "autowire" implementations, so if you go with a ready-made tool, make sure you read up on how that part works because it will generally make your life easier down the road.

When are .NET Core dependency injected instances disposed?

ASP.NET Core uses extension methods on IServiceCollection to set up dependency injection, then when a type is needed it uses the appropriate method to create a new instance:
AddTransient<T> - adds a type that is created again each time it's requested.
AddScoped<T> - adds a type that is kept for the scope of the request.
AddSingleton<T> - adds a type when it's first requested and keeps hold of it.
I have types that implement IDisposable and that will cause problems if they aren't disposed - in each of those patterns when is Dispose actually called?
Is there anything I need to add (such as exception handling) to ensure that the instance is always disposed?
The resolved objects have the same life-time/dispose cycle as their container, that's unless you manually dispose the transient services in code using using statement or .Dispose() method.
In ASP.NET Core you get a scoped container that's instantiated per request and gets disposed at the end of the request. At this time, scoped and transient dependencies that were created by this container will get disposed too (that's if they implement IDisposable interface), which you can also see on the source code here.
public void Dispose()
{
lock (ResolvedServices)
{
if (_disposeCalled)
{
return;
}
_disposeCalled = true;
if (_transientDisposables != null)
{
foreach (var disposable in _transientDisposables)
{
disposable.Dispose();
}
_transientDisposables.Clear();
}
// PERF: We've enumerating the dictionary so that we don't allocate to enumerate.
// .Values allocates a ValueCollection on the heap, enumerating the dictionary allocates
// a struct enumerator
foreach (var entry in ResolvedServices)
{
(entry.Value as IDisposable)?.Dispose();
}
ResolvedServices.Clear();
}
}
Singletons get disposed when the parent container gets disposed, usually means when the application shuts down.
TL;DR: As long as you don't instantiate scoped/transient services during application startup (using app.ApplicationServices.GetService<T>()) and your services correctly implement Disposable interface (like pointed in MSDN) there is nothing you need to take care of.
The parent container is unavailable outside of Configure(IApplicationBuilder app) method unless you do some funky things to make it accessible outside (which you shouldn't anyways).
Of course, its encouraged to free up transient services as soon as possible, especially if they consume much resources.

InRequestScope disposes entitycontext for DelegatingHandlers

When I bind my context as InRequestScope, the context is disposed when the code in DelegatingHandler is called (instantiated in Application_Start and executed before controllers are initialized). If I use InTransientScope, then it works but I want 1 context for everything. Based on this answer here, it is the correct way to have 1 context.
Global.asax
static void Configure(HttpConfiguration config)
{
var kernel = NinjectWebCommon.Bootstrapper.Kernel;
config.MessageHandlers.Add(new ApiKeyHandler(kernel.Get<IApiService>()));
}
Bindings
//if i remove InRequestScope here, everything works.
kernel.Bind<EntityDatabaseContext>().ToMethod(context => new EntityDatabaseContext()).InRequestScope();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
//repositories
kernel.Bind<IRepository<Application>>().To<Repository<Application>>().InRequestScope();
//services
kernel.Bind<IApiService>().To<ApiService>().InRequestScope();
So Whenever SendAsync gets called in ApiKeyHandler, the context was already disposed. But when a controller is called (after calling the ApiKeyHandler), the context is fine. I'm not too sure what is going on. If it cannot work with InRequestScope, how can I accomplish it like how the answer in the linked question did it? 1 context InTransientScope and all others in InRequestScope?
Using a transient or singleton scoped context for your message handler gives you the limitation that all the entities will be cached for the message handler. E.g. if an entity is changed/deleted or a new one is added your message handler will never adapt to that change. This can be ok in some scenarios where the data is never changed.
If you need to operate on up to date data that will change you can't use these scopes. But InRequestScope means that you have to create a new instance of the service every time using a factory (see factory extension). That way you can have the context in request scope.

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.

Entity Framework and Object Context lifetime in ASP.NET MVC

I'm using Entity Framework in my project, and I have the problem that, once I pass my entities to a View (keep in mind that these entities have lazy-initialized objects along the lines of: Products.Owner, where owner is an object that is lazily initialized) I get a run-time exception telling me that the ObjectContext is out of scope.
Now this makes sense since I am getting the entities from a Service with a using (.... entities...) { .... } statement, which means it is disposed when the result is returned.
How would I get around this and have an Object Context that is alive from start to end. Thanks.
One option is to associate the repository with the Request, and have the Repository implement IDisposable, and have the Dispose method dispose of the contained ObjectContext, rather than using the more familiar using pattern inside your controller actions.

Resources