This may be something to be solved with Autofac nested scopes, but I have not been able to make enough of the documentation to figure it out myself.
I think what I am looking for is like a per-HTTP-request singleton, but the place of the request is taken by the lifetime of another object.
There is a class SubSystem, of which a new instance is created (resolved from the container, potentially through a factory class) every time new data is loaded into the application (the old data and SubSystem instance are discarded).
Then there are classes SomeFeature, implementing IFeature, and SomeService, implementing ISomeService.
SubSystem has dependencies on both IFeature and IService, while SomeFeature takes a dependency on IService. So the object graph looks like this:
SubSystem
└> SomeService : IService <─┐
└> SomeFeature : IFeature ├─── same instance
└> SomeService : IService <─┘
IFeature is only required in one place, so a transient registration is fine here. IService on the other hand must be resolved to the same instance for all dependencies within this subgraph, but when new data is loaded and a new SubSystem instance is created, its subgraph must get its own new "per-request singleton" IService instance.
The reason for discarding the instances is that they cache information from the loaded data for performance reasons, which will not be valid anymore when new data is loaded. I am currently using real singleton instances that have their local state reset via an event raised in the SubSystem constructor, but that is clearly a less than optimal solution.
As I said, I'd like this to work like InstancePerHttpRequest(), but as "instance per SubSystem".
Is there a way to achieve this using the Autofac API?
The option I think you're looking for is:
.InstancePerOwned<SubSystem>()
If you only consume SubSystem in one place, just take a dependency on Owned<SubSystem> at that point, and make sure you Dispose() the Owned<T> in the consuming component's Dispose() method.
For something a bit more transparent, assuming you can create ISubSystem to go with SubSystem you can do this:
builder.RegisterType<SubSystem>()
.InstancePerOwned<SubSystem>();
builder.RegisterType<SubSystemGraph>()
.As<ISubSystem>()
// Appropriate sharing here...
;
Where SubSystemGraph is:
class SubSystemGraph: ISubSystem, IDisposable
{
readonly Owned<SubSystem> _root;
public SubSystemGraph(Owned<SubSystem> root)
{
_root = root;
}
public void Dispose()
{
_root.Dispose();
}
// Methods of ISubSystem delegate to _root.Value
public void Foo()
{
_root.Value.Foo();
}
}
(This could be packaged up into a nicer interface on Autofac but it's not all that common in practice.)
Related
How do I register types which take another registered type as a parameter and also simple types (like an integer)?
public interface IDeviceManager
{
// implementation omitted.
}
public class DeviceManager : IDeviceManager
{
public DeviceManager(IDeviceConfigRepository configRepo, int cacheTimeout)
{
// implementation omitted
}
}
I do have a container registration for the IDeviceConfigRepository. That's ok. But how do I create an instance of DeviceManager with the configured dependency and passing along an integer of my choice in composition root?
I thought about creating a factory.
public class DeviceManagerFactory : IDeviceManagerFactory
{
private readonly Container _container;
public DeviceManagerFactory(Container container)
{
_container = container;
}
public DeviceManager Create(int minutes)
{
var configRepo = _container.GetInstance<IDeviceConfigurationRepository>();
return new DeviceManager(configRepo, minutes);
}
}
This is pretty simple.
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
public class ExampleClassUsingDeviceManager
{
private readonly DeviceManager _deviceManager;
public ExampleClassUsingDeviceManager(DeviceManager deviceManager, ...)
{
_deviceManage = deviceManager;
}
// actions...
}
For this to work and to avoid circular dependencies I would probably have to move the factory from the "application" project (as opposed to class libraries) where the composition root is to the project where the DeviceManager is implemented.
Is that OK? It would of course mean passing around the container.
Any other solutions to this?
EDIT
In the same project for other types I am using parameter objects to inject configuration into my object graph. This works OK since I only have one class instance per parameter object type. If I had to inject different parameter object instances (for example MongoDbRepositoryOptions) into different class instances (for example MongoDbRepository) I would have to use some kind of named registration - which SimpleInjector doesn't support. Even though I only have one integer the parameter object pattern would solve my problem. But I'm not too happy about this pattern knowing it will break as soon as I have multiple instances of the consuming class (i.e. MongoDbRepository).
Example:
MongoDbRepositoryOptions options = new MongoDbRepositoryOptions();
MongoDbRepositoryOptions.CollectionName = "config";
MongoDbRepositoryOptions.ConnectionString = "mongodb://localhost:27017";
MongoDbRepositoryOptions.DatabaseName = "dev";
container.RegisterSingleton<MongoDbRepositoryOptions>(options);
container.RegisterSingleton<IDeviceConfigurationRepository, MongoDbRepository>();
I am excited to hear how you deal best with configurations done at composition root.
Letting your DeviceManagerFactory depend on Container is okay, as long as that factory implementation is part of your Composition Root.
Another option is to inject the IDeviceConfigRepository into the DeviceManagerFactory, this way you can construct a DeviceManager without the need to access the container:
public class DeviceManagerFactory : IDeviceManagerFactory {
private readonly IDeviceConfigurationRepository _repository;
public DeviceManagerFactory(IDeviceConfigurationRepository repository) {
_repository = repository;
}
public DeviceManager Create(int minutes) {
return new DeviceManager(_repository, minutes);
}
}
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
In general I would say that factories are usually the wrong abstraction, since they complicate the consumer instead of simplifying them. So you should typically depend on the service abstraction itself (instead of depending on a factory abstraction that can produces service abstraction implementations), or you should inject some sort of proxy or mediator that completely hides the existence of the service abstraction from point of view of the consumer.
#DavidL points at my blog post about runtime data. I'm unsure though whether the cacheTimeout is runtime data, although you seem to be using it as such, since you are passing it in into the Create method of the factory. But we're missing some context here, to determine what's going on. My blog post still stands though, if it is runtime data, it's an anti-pattern and in that case you should
pass runtime data through method calls of the API
or
retrieve runtime data from specific abstractions that allow resolving runtime data.
UPDATE
In case the value you are using is an application constant, that is read through the configuration file, and doesn't change during lifetime of the application, it is perfectly fine to inject it through the constructor. In that case it is not a runtime value. There is also no need for a factory.
There are multiple ways to register this in Simple Injector, for instance you can use a delegate to register the DeviceManager class:
container.Register<DeviceManager>(() => new DeviceManager(
container.GetInstance<IDeviceConfigRepository>(),
cacheTimeout: 15));
Downside of this approach is that you lose the ability of Simple Injector to auto-wire the type for you, and you disable Simple Injector's ability to verify, diagnose and visualize the object graph for you. Sometimes this is fine, while other times it is not.
The problem here is that Simple Injector blocks the registration of primitive types (because they cause ambiguity) while not presenting you with a clean way to make the registration. We are considering (finally) adding such feature in v4, but that doesn't really address your current needs.
Simple Injector doesn't easily allow you to specify a primitive dependency, while letting the container auto-wire the rest. Simple Injector's IDependencyInjectionBehavior abstraction allows you to override the default behavior (which is to disallow doing this). This is described here, but I usually advice against doing this, because it is usually requires quite a lot of code.
There are basically two options here:
Abstract the specific logic that deals with this caching out of the class and wrap it in a new class. This class will have just the cacheTimeout as its dependency. This is of course only useful when there actually is logical to abstract and is usually only logical when you are injecting that primitive value into multiple consumers. For instance, instead of injecting a connectionstring into multiple classes, you're probably better of injecting an IConnectionFactory into those classes instead.
Wrap the cacheTimeout value into a complex data container specific for the consuming class. This enables you to register that type, since it resolves the ambiguity issue. In fact, this is what you yourself are already suggesting and I think this is a really good thing to do. Since those values are constant at runtime, it is fine to register that DTO as singleton, but make sure to make it immutable. When you give each consumer its own data object, you won't have to register multiple instances of those, since they are unique. Btw, although named registations aren't supported, you can make conditional or contextual registrations using RegisterConditional and there are other ways to achieve named registrations with Simple Injector, but again, I don't think you really need that here.
I'm getting StackoverflowException's in my implementation of the decorator pattern when using dependency injection. I think it is because I'm "missing" something from my understanding of DI/IoC.
For example, I currently have CustomerService and CustomerServiceLoggingDecorator. Both classes implement ICustomerService, and all the decorator class does is use an injected ICustomerService but adds some simple NLog logging so that I can use logging without affecting the code in CustomerService while also not breaking the single responsibility principle.
However the problem here is that because CustomerServiceLoggingDecorator implements ICustomerService, and it also needs an implementation of ICustomerService injected into it to work, Unity will keep trying to resolve it back to itself which causes an infinite loop until it overflows the stack.
These are my services:
public interface ICustomerService
{
IEnumerable<Customer> GetAllCustomers();
}
public class CustomerService : ICustomerService
{
private readonly IGenericRepository<Customer> _customerRepository;
public CustomerService(IGenericRepository<Customer> customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException(nameof(customerRepository));
}
_customerRepository = customerRepository;
}
public IEnumerable<Customer> GetAllCustomers()
{
return _customerRepository.SelectAll();
}
}
public class CustomerServiceLoggingDecorator : ICustomerService
{
private readonly ICustomerService _customerService;
private readonly ILogger _log = LogManager.GetCurrentClassLogger();
public CustomerServiceLoggingDecorator(ICustomerService customerService)
{
_customerService = customerService;
}
public IEnumerable<Customer> GetAllCustomers()
{
var stopwatch = Stopwatch.StartNew();
var result = _customerService.GetAllCustomers();
stopwatch.Stop();
_log.Trace("Querying for all customers took: {0}ms", stopwatch.Elapsed.TotalMilliseconds);
return result;
}
}
I currently have the registrations setup like this (This stub method was created by Unity.Mvc):
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();
// Register the database context
container.RegisterType<DbContext, CustomerDbContext>();
// Register the repositories
container.RegisterType<IGenericRepository<Customer>, GenericRepository<Customer>>();
// Register the services
// Register logging decorators
// This way "works"*
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new CustomerService(
new GenericRepository<Customer>(
new CustomerDbContext()))));
// This way seems more natural for DI but overflows the stack
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>();
}
So now I'm not sure of the "proper" way of actually creating a decorator with dependency injection. I based my decorator on Mark Seemann's answer here. In his example, he is newing up several objects that get passed into the class. This is how my it "works"* snippet works. However, I think I have missed a fundamental step.
Why manually create new objects like this? Doesn't this negate the point of having the container doing the resolving for me? Or should I instead do contain.Resolve() (service locator) within this one method, to get all the dependencies injected still?
I'm slightly familiar with the "composition root" concept, which is where you are supposed to wire up these dependencies in one and only one place that then cascades down to the lower levels of the application. So is the Unity.Mvc generated RegisterTypes() the composition root of an ASP.NET MVC application? If so is it actually correct to be directly newing up objects here?
I was under the impression that generally with Unity you need to create the composition root yourself, however, Unity.Mvc is an exception to this in that it creates it's own composition root because it seems to be able to inject dependencies into controllers that have an interface such as ICustomerService in the constructor without me writing code to make it do that.
Question: I believe I'm missing a key piece of information, which is leading me to StackoverflowExceptions due to circular dependencies. How do I correctly implement my decorator class while still following dependency injection/inversion of control principles and conventions?
Second question: What about if I decided I only wanted to apply the logging decorator in certain circumstances? So if I had MyController1 that I wished to have a CustomerServiceLoggingDecorator dependency, but MyController2 only needs a normal CustomerService, how do I create two separate registrations? Because if I do:
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>();
container.RegisterType<ICustomerService, CustomerService>();
Then one will be overwritten meaning that both controllers will either both have a decorator injected or a normal service injected. How do I allow for both?
Edit: This is not a duplicate question because I am having problems with circular dependencies and a lack of understanding of the correct DI approach for this. My question applies to a whole concept not just the decorator pattern like the linked question.
Preamble
Whenever you are having trouble with a DI Container (Unity or otherwise), ask yourself this: is using a DI Container worth the effort?
In most cases, the answer ought to be no. Use Pure DI instead. All your answers are trivial to answer with Pure DI.
Unity
If you must use Unity, perhaps the following will be of help. I haven't used Unity since 2011, so things may have changed since then, but looking up the issue in section 14.3.3 in my book, something like this might do the trick:
container.RegisterType<ICustomerService, CustomerService>("custSvc");
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new ResolvedParameter<ICustomerService>("custSvc")));
Alternatively, you may also be able to do this:
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new ResolvedParameter<CustomerService>()));
This alternative is easier to maintain because it does not rely on named services, but has the (potential) disadvantage that you can't resolve CustomerService through the ICustomerService interface. You probably shouldn't be doing that anyway, so it ought not to be an issue, so this is probably a better alternative.
Question: I believe I'm missing a key piece of information, which is leading me to StackoverflowExceptions due to circular dependencies. How do I correctly implement my decorator class while still following dependency injection/inversion of control principles and conventions?
As was already pointed out the best way to do this is with the following construct.
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
This allows you to specify how the parameters are resolved by type. You could also do it by name but by type is a cleaner implementation and allows for better checking during compile time as a change or mistype in a string will not be caught. Note that the only minute difference between this code part and the code offered by Mark Seemann is a correction in the spelling of InjectionConstructor. I will not elaborate on this part any more as there is nothing else to add that Mark Seemann has not already explained.
Second question: What about if I decided I only wanted to apply the logging decorator in certain circumstances? So if I had MyController1 that I wished to have a CustomerServiceLoggingDecorator dependency, but MyController2 only needs a normal CustomerService, how do I create two separate registrations?
You can do this using the way specified above using the Fluent notation OR using named dependency with a dependency override.
Fluent
This registers the controller with the container and specifies an overrload for that type in the constructor. I prefer this approach over the second but it just depends on where you want to specify the type.
container.RegisterType<MyController2>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
Named dependency
You do this the exact same way, you register both of them like so.
container.RegisterType<ICustomerService, CustomerService>("plainService");
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
The difference here is that you use a named dependency instead for the other types that can be resolved using the same interface. This is because the interface needs to be resolved to exactly one concrete type every time a resolve is done by Unity so you can not have multiple unnamed registered types that are registered to the same interface. Now you can specify an override in your controller constructor using an attribute. My example is for a controller named MyController2 and I added the Dependency attribute with the name also specified above in the registration. So for this constructor a CustomerService type will be injected instead of the default CustomerServiceLoggingDecorator type. MyController1 will still use the default unnamed registration for ICustomerService which is type CustomerServiceLoggingDecorator.
public MyController2([Dependency("plainService")]ICustomerService service)
public MyController1(ICustomerService service)
There are also ways to do this when you manually resolve the type on the container itself, see Resolving Objects by Using Overrides. The problem here is that you need access to the container itself to do this which is not recommended. As an alternative you could create a wrapper around the container that you then inject into the Controller (or other type) and then retrieve a type that way with overrides. Again, this gets a bit messy and I would avoid it if possible.
Building upon Mark's second answer I'd look to registering the CustomerService with a InjectionFactory and only register it with the service type without it's interface like:
containter.RegisterType<CustomerService>(new InjectionFactory(
container => new CustomerService(containter.Resolve<IGenericRepository<Customer>>())));
This would then allow, as in Mark's answer, for you to register the logging object like:
containter.RegisterType<ICutomerService, CutomerServiceLoggingDecorator>(new InjectionConstructor(
new ResolvedParameter<CustomerService>()));
This is basically the same technique that I use whenever I require something to be lazily loaded as I don't want my objects to depend upon Lazy<IService> and by wrapping them in proxy allows me to only inject IService but have it resolved lazily through the proxy.
This will also allow you to pick and choose where either the logging object or the normal object is injected instead of requiring magic strings by simply resolving a CustomerService for your object instead of the ICustomerService.
For a logging CustomerService:
container.Resolve<ICustomerService>()
Or for a non-logging CustomerService:
container.Resolve<CustomerService>()
I'm trying to implement IoC in my app. I have this model:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
At some point in my app I need to get a IComponent. My app uses a IoC container (Unity). I can register Service with the container but I can't do the same for Component b/c of its dependency runtimeValue. According to this I have to use a factory and inject that wherever I need to get a IComponent:
interface IComponentFactory
IComponent CreateComponent(object runtimeValue)
class ComponentProvider : IComponentProvider
ComponentProvider(IComponentFactory factory) { }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = factory.CreateComponent(runtimeValue)
return _component
}
// other methods
I must be able to register the factory with the container, so it must have only static dependencies. At the same time it must be able to provide a service instance of type IService required to create a component.
Here is the factory implementation. The only thing I could think of was to use a Func<> delegate as dependency:
class ComponentFactory : IComponentFactory
ComponentFactory(Func<IService> serviceFactoryDelegate)
IComponent CreateComponent(object runtimeValue) {
return new Component(serviceFactoryDelegate.Invoke(), runtimeValue)
}
... and register the delegate with the container as static factory, so that it calls back the container to resolve the service (I'm using Unity 1.2 on .net 2.0):
Container
.Configure<IStaticFactoryConfiguration>()
.RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
Now I can use the container to resolve a ComponentProvider and get a component based on a runtime value:
// this happens inside CompositionRoot
provider = Container.Resovle<IComponentProvider>()
component = provider.CreateAndCacheComponent("the component")
Now I have some questions about this:
I'm not happy that the factory calls new Component(...). Isn't this poor man's DI?
Does the Hollywood principle still stand when using Func<IService> on factory's constructor? I mean, it ultimately calls container.Resolve<>... kind of like SL. The only difference is the code is in the container registration part of the app rather than inside the factory class.
Is there anything (else) wrong with this implementation, as far as DI and IoC are concerned?
It's a big step away from Poor Man's DI, but it would be nice if you didn't have to change this factory method every time a new dependency gets added to the Component's constructor.
This isn't a problem per se. Think of it like you're injecting an anonymous factory class. It can still be mocked for unit testing, and the bindings can be changed, so you're still getting the benefits of DI. But it is an added layer of abstraction which is probably not necessary. You can still avoid it in this case by injecting the IService directly into the factory, rather than a Func.
Typically when using dependency injection, you want to inject services rather than values. The fact that you're finding that you have to have both may indicate that you need to reconsider your class's API. For example, maybe you should be passing the value in to the methods on the class rather than the constructor. It's hard to say what the best approach would be without knowing more details.
No, it isn't. The whole purpose of a factory is to create an instance of a concrete class.
Basically, yes, but as I already asked in my comment, I don't see why this is necessary. You could inject an instance of IService directly
It's a bit more complicated than it needs to be. Why the double redirection IComponentProvider -> IComponentFactory? It looks like IComponentFactory doesn't add any benefit.
Implement ComponentProvider like this:
class ComponentProvider : IComponentProvider
{
ComponentProvider(IService service) { _service = service; }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = new Component(_service, runtimeValue);
return _component;
}
This would give you the following benefits:
You get rid of the unnecessary interface IComponentFactory along with the corresponding implementation.
No need to register a factory for IService
Generally speaking, how you implement this it depends on what you really need:
"runtimeValue" can be the same throughout the runtime, e.g. a connection string that is read from the settings. In that case, there would be no need for a factory / provider, you could simply new up the instance and register it with the container. Everyone who needs an IComponent requests one in the constructor instead of the provider.
You would only implement a factory and pass that as a dependency around if the "runtimeValue" really changes between calls to CreateAndCacheComponent.
To question 1: there is nothing wrong with calling new in the factory. You have isolated instantiation to one place in your application; you just made that one place the factory instead of the container.
If you ever needed to mock or change implementations, you would just mock or change the factory implementation, rather than the Component alone.
I just started migrating my web application to fully use Windsor IOC. Here is a little problem I am encountering;
I have couple of static classes which I used to store some application level global values
EG (Simplified version of the class):
public static class SiteInfo
{
public static Language Language = (Language)byte.Parse(SiteInfo.Val("language"));
public static string Code = Site.Code;
public static string Name = Site.Name;
public static SiteCachedData CachedData { get; set; }
public static Site Site { get; set; }
public static void Init()
{
//Get site info from DB here
//I need to inject _SiteRepository here but I can't
//since I don't have access to the constructor
}
}
I am new to IOC and I understand static classes are advised to be prevented. What is the good practice to handle this situation? I am thinking of converting this to a singleton but I am not sure if that is my best bet.
This is one of the reasons why I like to avoid static classes --they are hard to inject or invert control. They usually have to know intimate details of several low level classes. Since they are static classes you can leave them because they are already available to all of the other classes and don't require injection.
One trick that I've done is to create a second class that delegates into the static class. You can then put an interface onto the new class and get into an IoC framework easier.
public static class StaticClass
{
public static object Method()
}
public class NonstaticClass : INewInterface
{
public object Method()
{
return StaticClass.Method();
}
}
The good part of this refactor is that you can go method by method and then determine new objects and interfaces as you go. Eventually you may be able to get rid of the original static class. You would also register the new classes as singleton instances so that only one instance exists at a time.
In the context of an IoC container, it's a bit ambiguous to say 'convert it to a singleton'. If you mean the singleton design pattern, you probably shouldn't do it that way, as there are better alternatives in the IoC world.
IoC containers perform two main roles: to resolve dependencies between components, and to manage the lifetime of components. A container manages the lifetime of its components by deciding when to create and destroy component instances.
For example, when you call container.Resolve<SiteInfo>(), the container has to decide whether to re-use an existing SiteInfo instance or create a new one. How does the container decide? Well, when you register SiteInfo with the container, you can tell the container how you would like it to behave. If you register it as a Singleton, the container will only create a SiteInfo instance on the first call to container.Resolve<SiteInfo>(); on subsequent calls, it re-uses the existing SiteInfo instance.
The advantage of this technique over the singleton pattern is flexibility. If you use the design pattern, your SiteInfo class will forever be a singleton (unless you refactor). By using the container to manage the lifetime, you can change your mind later and just change the container registration code. Consumers of the component don't need to (and shouldn't) care whether the container provides them with a new instance or re-uses an existing one - they just call container.Resolve().
I'm not familiar with Windsor (I use Autofac), but it looks like you have two ways of registering a component as a singleton (I'm sure someone will correct me if this is wrong):
container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton)
or,
container.Register( Component.For<SiteInfo>()
.LifeStyle.Singleton );
However, a word of warning. In your example, your SiteInfo class has a dependency on the _SiteRepository class. You will therefore also need to register a _SiteRepository instance as a singleton in the container, so that it is available when the container resolves the SiteInfo. This _SiteRepository instance will remain in memory for the lifetime of the container, i.e. for the lifetime of the Web application, because it's a singleton. If the repository keeps a DB connection open, therefore, that connection will remain open for the same lifetime.
For this sort of reason, an alternative lifestyle is per-web-request - in other words, the container will create a new instance of your SiteInfo class once per web request. The per-web-request lifestyle is discussed in another question.
You can register an single instanec of a class in your container, so it behaves like a singleton. The container gives you the same instance every time.
I'm finally wrapping my head around IoC and DI in C#, and am struggling with some of the edges. I'm using the Unity container, but I think this question applies more broadly.
Using an IoC container to dispense instances that implement IDisposable freaks me out! How are you supposed to know if you should Dispose()? The instance might have been created just for you (and therefor you should Dispose() it), or it could be an instance whose lifetime is managed elsewhere (and therefor you'd better not). Nothing in the code tells you, and in fact this could change based on configuration!!! This seems deadly to me.
Can any IoC experts out there describe good ways to handle this ambiguity?
You definitely do not want to call Dispose() on an object that was injected into your class. You can't make the assumption that you are the only consumer. Your best bet is to wrap your unmanaged object in some managed interface:
public class ManagedFileReader : IManagedFileReader
{
public string Read(string path)
{
using (StreamReader reader = File.OpenRead(path))
{
return reader.ReadToEnd();
}
}
}
That is just an example, I would use File.ReadAllText(path) if I were trying to read a text file into a string.
Another approach is to inject a factory and manage the object yourself:
public void DoSomething()
{
using (var resourceThatShouldBeDisposed = injectedFactory.CreateResource())
{
// do something
}
}
AutoFac handles this by allowing the creation of a nested container. When the container is finished with, it automatically disposes of all IDisposable objects within it. More here.
.. As you resolve services, Autofac tracks disposable (IDisposable) components that are resolved. At the end of the unit of work, you dispose of the associated lifetime scope and Autofac will automatically clean up/dispose of the resolved services.
This has puzzled me frequently as well. Though not happy about it, I always came to the conclusion that never returning an IDisposable object in a transient way was best.
Recently, I rephrased the question for myself: Is this really an IoC issue, or a .net framework issue? Disposing is awkward anyway. It has no meaningful functional purpose, only technical. So it's more a framework issue that we have to deal with, than an IoC issue.
What I like about DI is that I can ask for a contract providing me functionality, without having to bother about the technical details. I'm not the owner. No knowledge about which layer it's in. No knowledge about which technologies are required to fulfil the contract, no worries about lifetime. My code looks nice and clean, and is highly testable. I can implement responsibilities in the layers where they belong.
So if there's an exception to this rule that does require me to organise the lifetime, let's make that exception. Whether I like it or not. If the object implementing the interface requires me to dispose it, I want to know about it since then I am triggered to use the object as short as possible. A trick by resolving it using a child container which is disposed some time later on might still cause me keeping the object alive longer than I should. The allowed lifetime of the object is determined when registering the object. Not by the functionality that creates a child container and holds on to that for a certain period.
So as long as we developers need to worry about disposing (will that ever change?) I will try to inject as few transient disposable objects as possible.
1. I try to make the object not IDisposable, for example by not keeping disposable objects on class level, but in a smaller scope.
2. I try to make the object reusable so that a different lifetime manager can be applied.
If this is not feasible, I use a factory to indicate that the user of the injected contract is owner and should take responsibility for it.
There is one caveat: changing a contract implementer from non-disposable to disposable will be a breaking change. At that time the interface will no longer be registered, but the interface to the factory. But I think this applies to other scenario's as well. Forgetting to use a child container will from that moment on give memory issues. The factory approach will cause an IoC resolve exception.
Some example code:
using System;
using Microsoft.Practices.Unity;
namespace Test
{
// Unity configuration
public class ConfigurationExtension : UnityContainerExtension
{
protected override void Initialize()
{
// Container.RegisterType<IDataService, DataService>(); Use factory instead
Container.RegisterType<IInjectionFactory<IDataService>, InjectionFactory<IDataService, DataService>>();
}
}
#region General utility layer
public interface IInjectionFactory<out T>
where T : class
{
T Create();
}
public class InjectionFactory<T2, T1> : IInjectionFactory<T2>
where T1 : T2
where T2 : class
{
private readonly IUnityContainer _iocContainer;
public InjectionFactory(IUnityContainer iocContainer)
{
_iocContainer = iocContainer;
}
public T2 Create()
{
return _iocContainer.Resolve<T1>();
}
}
#endregion
#region data layer
public class DataService : IDataService, IDisposable
{
public object LoadData()
{
return "Test data";
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
/* Dispose stuff */
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
#endregion
#region domain layer
public interface IDataService
{
object LoadData();
}
public class DomainService
{
private readonly IInjectionFactory<IDataService> _dataServiceFactory;
public DomainService(IInjectionFactory<IDataService> dataServiceFactory)
{
_dataServiceFactory = dataServiceFactory;
}
public object GetData()
{
var dataService = _dataServiceFactory.Create();
try
{
return dataService.LoadData();
}
finally
{
var disposableDataService = dataService as IDisposable;
if (disposableDataService != null)
{
disposableDataService.Dispose();
}
}
}
}
#endregion
}
I think in general the best approach is to simply not Dispose of something which has been injected; you have to assume that the injector is doing the allocation and deallocation.
This depends on the DI framework. Some frameworks allow you to specify whether you want a shared instance (always using the same reference) for every dependency injected. In this case, you most likely do not want to dispose.
If you can specify that you want a unique instance injected, then you will want to dispose (since it was being constructed for you specifically). I'm not as familiar with Unity, though - you'd have to check the docs as to how to make this work there. It's part of the attribute with MEF and some others I've tried, though.
Putting a facade in front of the container can resolve this as well. Plus you can extend it to keep track of a more rich life cycle like service shutdowns and startups or ServiceHost state transitions.
My container tends to live in an IExtension that implements the IServiceLocator interface. It is a facade for unity, and allows for easy access in WCf services. Plus I have access to the service events from the ServiceHostBase.
The code you end up with will attempt to see if any singleton registered or any type created implements any of the interfaces that the facade keeps track of.
Still does not allow for the disposing in a timely manner as you are tied to these events but it helps a bit.
If you want to dispose in a timely manner (aka, now v.s. upon service shutdown). You need to know that the item you get is disposable, it is part of the business logic to dispose of it, so IDisposable should be part of the interface of the object. And there probably should be verification of expectations untitests related to the dispose method getting called.
In the Unity framework, there are two ways to register the injected classes: as singletons (you get always the same instance of the class when you resolve it), or such as you get a new instance of the class on each resolution.
In the later case, you have the responsibility of disposing the resolved instance once you don't need it (which is a quite reasonable approach). On the other hand, when you dispose the container (the class that handles object resolutions), all the singleton objects are automatically disposed as well.
Therefore, there are apparently no issues with injected disposable objects with the Unity framework. I don't know about other frameworks, but I suppose that as long as a dependency injection framework is solid enough, it for sure handles this issue in one way or another.