I'm working with StructureMap for my IoC needs.
To make things pleasantly testable, I'm passing IContainer instances around wherever possible, usually as constructor parameters. As a convenience, I'd like to be able to fall back to using ObjectFactory for a parameterless constructor.
The simplest way (I thought) to do this would be to simply get the IContainer the ObjectFactory class wraps and pass that to the other constructor. Unfortunately, I can't find anywhere this instance is publicly exposed.
The question is:
Is there a way to get the IContainer within ObjectFactory so I can handle it as simply as a user-supplied instance?
Alternatively, is there a way to duplicate the configuration of the ObjectFactory into a new Container instance?
Example:
I would like to be able to do the following:
public class MyClass
{
public MyClass()
{
Container = ... // The ObjectFactory container instance.
}
public MyClass(IContainer container)
{
Container = container;
}
public IContainer Container { get; private set; }
}
ObjectFactory exposes a Container property which gives you the IContainer you are looking for.
Anytime you need an IContainer (which should not be often) you can always take a dependency on it in your class ctor.
public class INeedAContainer
{
private readonly IContainer _container;
public INeedAContainer(IContainer container)
{
_container = container;
}
// do stuff
}
I do not think there is a way to clone an IContainer. There is a container.GetNestedContainer() method which allows you to keep your transients the same for the lifetime of the nested container. Nested containers are often used within a "using" statement and are very handy for controlling the state of things like database transaction boundaries.
Related
I have read multiple articles about whether or not to do resource intensive operations in the constructor. Some of them say if it doesn't affect SRP or Testability then it is fine. I want an opinion on best practices for this scenario.
I am following the Composition Root principle mentioned here in my ASP.Net WebApi2 project and my controllers have got their dependent objects injected. Instead of injecting just a few dependencies, I want to inject the entire container and have any of the dependencies available. I have this class design where I am setting up the container property in the constructor. I dont know if this qualifies as bad practice.
public class AppContainer : IAppContainer
{
private readonly ContainerBuilder _builder ;
private IContainer _container ;
public AppContainer ()
{
_builder = new ContainerBuilder();
_builder.RegisterAssemblyModules(_assembly);
_container = _builder.Build();
}
public ContainerBuilder ContainerBuilder
{
get { return _builder; }
}
public IContainer Container
{
get { return _container;}
}
}
Is it bad design to call the .Build() in the constructor as done above? I want to do this so that the AppContainer's properties are initialized at the time of creation of the instance and not waiting for some method to be called for the properties to hold value.
Now in my controller instead of having something like this
public class HomeController : ApiController
{
private readonly IBusiness _bus;
public HomeController(IBusiness bus)
{
_bus = bus;
}
I can have something like this and expose the container directly. This way my controller's constructor definitions don't change everytime I needed a new dependency injected in.
public class HomeController : ApiController
{
private readonly IAppContainer _container;
public HomeController (IAppContainer container)
{
_container = container;
}
Is it bad design to call the .Build() in the constructor as done above?
In general, it is not recommended that you do a lot in constructors.
Also, I don't recommend that you use the AppContainer class at all. You are simply wrapping the container with the AppContainer class and using it as a service locator which is an anti-pattern.
Your classes should declare their dependencies explicitly in the constructor as in your first example of HomeController.
If you design your classes with the SOLID principles in mind, then your classes would be small and would not require a lot of dependencies so you almost wouldn't have to add new dependencies.
Please note that having too many dependencies (> ~3) might be an indication that you are violating the Single Responsibility Principle and is considered a code smell.
public class MyClassFactory : IMyClassFactory
{
private readonly IMySingleton _mySingleton;
private readonly IMyNonSingleton _myNonSingleton;
public MyClassFactory(
IMySingleton mySingleton,
IMyNonSingleton myNonSingleton
)
{
_mySingleton = mySingleton;
_myNonSingleton = myNonSingleton;
}
public IMyResult CreateMyResult(int resultId)
{
// right here - have i not arbitrarily extended the lifespan
// of _myNonSingleton?
//
return new MyResult(_mySingleton, _myNonSingleton, resultId);
}
}
With this setup, every new MyResult will get the same instance of IMyNonSingleton. Isn't the only way to solve this problem is to call Resolve on the container again every time you create a MyResult?
As well, if I do that, doesn't that start looking like a Service Locator pattern? At minimum, I'll be violating rules like "Don't call the container, it'll call you" and "you only call Resolve once" correct?
EDIT: The idea here is that IMySingleton has been registered in my container as a singleton and the other classes have not.
You have potential to extend lifetime of objects inadvertently, but it applies to all cases where lifetime of one object does not match lifetime of other.
Cases when it may not be a problem:
you may be asking container for the factory every time you need one or lifetime of the factory matches the shortest lifetime of objects that are used by the factory.
you actually need objects to have longer lifetime (or matching to factory)
objects with shorter lifetime don't care
Cases when it may be a problem:
your factory has longer lifetime (i.e. application), but objects must be created every time or at some other frequency managed by IOC container.
Workarounds:
integrate factory with container (i.e. pass container to factory and use its resolve methods to construct inner objects)
pass "creator" methods instead of instances into constructor to avoid direct dependency on container.
forgo factory altogether and integrate it directly into container initialization.
I.e. Microsoft Unity container registers both type and Func<T>, so your factory can immediately take dependency on creator functions like:
public MyClassFactory(
Func<IMySingleton> mySingleton,
Func<IMyNonSingleton> myNonSingleton
)...
1) I think you can change interface of IMyClassFactory to
public interface IMyClassFactory
{
IMyResult CreateMyResult(int resultId, IMyNonSingleton myNonSinglrton);
}
2) Or you need a IMyNonSingletonFactory to rewrite code like this
public class MyClassFactory : IMyClassFactory
{
private readonly IMySingleton _mySingleton;
private readonly IMyNonSingletonFactory _myNonSingletonFactory;
public MyClassFactory(
IMySingleton mySingleton,
IMyNonSingletonFactory myNonSingletonFactory
)
{
_mySingleton = mySingleton;
_myNonSingletonFactory = myNonSingletonFactory;
}
public IMyResult CreateMyResult(int resultId)
{
//you need your definition of INonSingletonFactory
return new MyResult(_mySingleton, _myNonSingletonFactory.Create(), resultId);
}
}
I have a class that needs a dependency injecting. As the class is already an implementation of another abstraction, and its 'sibling' implementations may not share the same dependencies, I am attempting to use property injection and not constructor injection.
(All these classes/interface names are just for illustrative purposes)
My IProvider abstraction:
public interface IProvider
{
void ProviderMethod();
}
My IProvider implementation (with the IData dependency I want to inject):
public class ProviderClass : IProvider
{
// How do I inject this dependency?
[Dependency]
public IData data { get; set; }
public void ProviderMethod()
{
// Can't do this as data == null!
data.DataMethod();
}
}
Another IProvider implementation (example to show that it doesn't have the same dependencies):
public class AnotherProviderClass : IProvider
{
// No data dependency here!!
public void ProviderMethod()
{
// Do other stuff here
}
}
Example IData abstraction and implementation:
public interface IData
{
void DataMethod();
}
public class DataClass : IData
{
public void DataMethod();
}
What I need to know is: How do I successfully inject the property dependency (IData) into ProviderClass using Unity (my IOC container of choice)?
I have tried all manner of Unity registering options (RegisterType, RegisterInstance, Resolve...) but my injected property always ends up as NULL. I want to do this right and not just force random code in until it just manages to work.
Or is there a better way of injecting (optional) dependencies into 'sibling' classes?
Incidentally, my initial IProvider implementations are created via an abstract factory, so maybe that might be another area I should focus this IData dependency on(?)
You should still use constructor injection because dependencies should hardly ever be optional.
You are trying to prevent constructor over-injection in the IProviderFactory implementation, and you probably don't want to inject the container into your factory to prevent falling into the Service Locator anti-pattern.
If however you define your IProviderFactory implementation INSIDE your Composition Root, you prevent yourself from doing Service Locator, even though you inject the container, since Service Locator is not about mechanics.
So you should define your ProviderFactory implementation as close to your Unity configuration as possible and it should look something like this:
public class ProviderFactory : IProviderFactory
{
private readonly Dictionary<string, Type> providerTypes;
private readonly Container container;
public ProviderFactory(Dictionary<string, Type> providerTypes,
Container container) {
this.providerTypes = providerTypes;
this.container = container;
}
public IProvider CreateProvider(string name) {
return (IProvider)this.container.Resolve(this.providerTypes[name]);
}
}
This implementation can be registered as singleton in Unity. This saves you from having to do constructor over-injection into your factory, while staying away from Service Locator.
I want to inject Container property via SimpleInjector. I didn't find any functionality of SimpleInjector for that.
Then I wanted to register self container to itself, but Container has no interface.
I want this functionality because I don't to transfer Container object via constructor - because why if I can use auto inject of register objects.
My usage idea:
var container = new Container();
container.Options.AutowirePropertiesWithAttribute<InjectableProperty>();
container.Register<ISomething, Something>(Lifestyle.Singleton);
ISomething:
public interface ISomething
{
void SomeMethod();
}
Something class:
public class Something : ISomething
{
public void SomeMethod()
{
var environment = _container.GetInstance<IEnvironment>();
environment.DoSomething();
}
[InjectableProperty] // - maybe it is not possible (I don't know it)
Container Container {get;set;}
}
Do you have any idea to achieve that?
Thank you very much.
Prevent having your application code depend upon the container. The only place in your application that should know about the existence of your DI library is the Composition Root (the place where you register all your dependencies).
Instead of letting each class call back into the container (which is called the Service Locator anti-pattern), prefer using Dependency Injection. With Dependency Injection you inject dependencies instead of asking for them.
So you can rewrite your class to the following:
public class Something : ISomething
{
private readonly IEnvironment environment;
public Something (IEnvironment environment)
{
this.environment = environment;
}
public void SomeMethod()
{
this.environment.DoSomething();
}
}
Also, prevent doing any logic in your constructors besides storing the incoming dependencies. This allows you to compose object graphs with confidence.
In some cases however, it can still be useful to inject the Container into another class. For instance when creating a factory class that is located inside the Composition Root. In that case you can still use constructor injection, like this:
// Defined in an application layer
public interface IMyFactory
{
IMyService CreateService();
}
// Defined inside the Composition Root
public class MyFactory : IMyFactory
{
private readonly Container container;
public MyFactory(Containter container)
{
this.container = container;
}
public IMyService CreateService(ServiceType type)
{
return type == ServiceType.A
? this.container.GetInstance<MyServiceA>()
: this.container.GetInstance<MyServiceB>();
}
}
If Simple Injector detects a Container constructor argument, it will inject itself into the constructor automatically.
I am trying to avoid the anti-pattern of Container.Resolve(). How do I change the following to use contructor injection?
Installers.cs
public void Install(Castle.Windsor.IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container
.Register(Component.For<IData>()
.ImplementedBy<Data>().LifeStyle.Singleton)
}
BootStrapper.cs
public class Bootstrapper
{
private static volatile IWindsorContainer _theWindsorContainer;
private static object syncRoot = new Object();
public static IWindsorContainer Container
{
get
{
if (_theWindsorContainer == null)
{
lock (syncRoot)
{
if (_theWindsorContainer == null)
{
_theWindsorContainer = new WindsorContainer().Install(FromAssembly.This());
}
}
}
return _theWindsorContainer;
}
}
}
OViewModel.cs
public IData ThisData {get;set;}
public OViewModel()
{
ThisData= Bootstrapper.Container.Resolve<IData>();
InitializeComponent();
}
How do I use Windsor Castle constructor injection to initialize the viewmodel and do constructor injection? Either InitializeComponentdoesn't get called or ThisData is null.
I wrote an article a few years ago about integrating Castle Windsor into WPF to achieve DI in your view models. It might be what you're looking for.
I'm not familiar with the particulars of Castle Windsor, but typically you would structure your OViewModel like this:
public class OViewModel
{
public IData ThisData { get; set; } //private set??
public OViewModel(IData _thisData)
{
ThisData = _thisData;
InitializeComponent();
}
}
That would be constructor injection. You can search for the term parameter injection for other ways of getting it done.
But basically the when an OViewModel is resolved by the container, it knows how to resolve an IData and will automatically resolve it for you.
Of course, this just backs things up -- whatever is creating the OViewModel needs to use container.Resolve and you don't want to do that. So you'll probably inject the view model (or an interface of it) (or a factory object) to that parent object. And so on back up the chain until you have single object that is the root of your application that you need to resolve from the container to get everything started.
Hopefully someone with more knowledge of the particulars of Castle Windsor can give you more details.