I am trying to use property injection for StructureMap in a plug-in style system.
ObjectFactory.Initialize(o => o.Scan(s =>
{
s.AssembliesFromPath("path_to_assemblies");
s.WithDefaultConventions();
});
Here is a sample implementation (purposely did not go deeper in defining T and TU as they are just simple classes)
public interface IBarService
{
void Baz();
}
public class BarService : IBarService
{
public void Baz() { /* implementation */ }
}
public abstract class PluginBase<T, TU> : IPlugin
where T : AClass, new()
where TU : BClass
{
protected PluginBase()
{
//some init code in the constructor
}
}
//Foo is created at run-time via Activator.CreateInstance()
public class FooPlugin : PluginBase<AClass, BClass>
{
[SetterProperty]
public IBarService BarService { get; set; }
public void Fooey()
{
BarService.Baz();
}
}
I want to auto-wire the property dependencies on all of these plug-ins that are created at run-time. I thought I'd start out with property injection and then move things to the constructor if the need arose.
If I do:
var obj = ObjectFactory.GetInstance<IBarService>();
anywhere in an instance of FooPlugin, I get the correct implementation and all is well.
If I do:
this.BarService.Baz();
I get a null reference exception because no instance of IBarService was set.
After I create my plug-in, if I do this:
ObjectFactory.BuildUp(pluginObject).
All is well and FooPlugin has the correct implementation of IBarService.
Is there any way to simply allow me to decorate my plugin properties with [SetterProperty] and have StructureMap automatically inject those when the Plugin is created without having to call ObjectFactory.BuildUp(pluginObject) ?
How are you creating your plugin instance in the cases where it doesn't work? Are you just doing new FooPlugin()?
If you do var plugin = ObjectFactory.GetInstance<PluginBase<AClass, BClass>>();, do you get the plugin with all the correct dependencies resolved?
If you are instantiating the object with "new", the container has no way to know that the instance needs dependencies resolved--it has no knowledge of that instance. Instances that need injected dependencies must be "managed by the container" so to speak.
You'll save yourself a lot of trouble if you just go the opposite route and inject all dependencies in the contstructor(s). This way there is a single place where you need to check if your objects are initialized properly...
Related
I'm trying to set up Registrations in Unity, and I'm having trouble getting exactly what I need.
Imagine I have the following definitions:
public interface ISomeInterface { ... }
public interface ISomeDependency { ... }
public class DependencyA : ISomeDependency { ... }
public class DependencyB : ISomeDependency { ... }
public class SomeClassA : ISomeInterface
{
public SomeClassA(ISomeDependency dep){ ... }
}
public class SomeClassB : ISomeInterface
{
public SomeClassB(ISomeDependency dep){ ... }
}
I then register them with Unity as follows:
Container.RegisterType<ISomeDependency, DependencyA>("DependencyA");
Container.RegisterType<ISomeDependency, DependencyB>("DependencyB");
Container.RegisterType<ISomeInterface, SomeClassA>("ClassA");
Container.RegisterType<ISomeInterface, SomeClassB>("ClassB");
I also register a factory that will build an ISomeInterface based off a key.
Container.RegisterType<Func<string, ISomeInterface>(new InjectionFactory(c=>
{
return new Func<string, ISomeInterface>(x=>
{
return c.Resolve<ISomeInterface>(x)
}
}));
(incidentally, if anyone knows a better way of creating keyed factories I'd welcome the tip)
How can I configure Unity such that when Unity builds me an instance of SomeClassA, it will also inject an instance of DependencyA? The same when Unity builds me an instance of SomeClassB, it will inject an instance of DependencyB.
Appreciate your help.
edit: corrected my typo
If you register two concrete types for one interface, Unity will not know which one to resolve to. You'll have to provide more information. One way to do that is to use a parameter override.
// Override the constructor parameter "dep" value
// Use DependencyA instead of other value
var result = container.Resolve<ISomeInterface>(
new ParameterOverride("dep", new DependencyA())
.OnType<SomeClassA>());
But, you've also registered bot SomeClassA and SomeClassB as type of ISomeInteface, so you'll also have to tell Unity which one of those implementations you want when you want an ISomeInterface.
Let's say in C# I have a class called A
public class A : IInterfaceA
{
[Dependency]
B _b;
}
Then in B class I have a constructor like this:
public class B
{
...
public B(string someParam) { ... }
...
}
Now, I register class A like this:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA");
and to resolve the interface I do:
_unityContainer.Resolve<IInterfaceA>("RegistrationA", new ParameterOverride("someParam", "The param."));
Now I want to know if it is good practice to resolve the class and pass the parameters like this or I should do it another way.
Thanks a lot :)
First of all the code you posted does not work: in fact you're overriding the parameter of class A, while in your code the constructor with the parameter is B.
Generally speaking, using parameter override is not a good practice in my opinion (unless some very specifical context like a console application or a web service using an existing container but it's avoidable in most cases) for these reason:
Using Resolve looks like a Service locator: anti-pattern nowadays. You will find a lot of discussion googling about.
Using ParameterOverride means that the client (the caller of Resolve) knows exactly the type mapped in the container and wants that type initialized with a specific parameter. But this is just the opposite of inversion of control.
The best way is to use an abstract factory. You can add in your code and use a more flexible and SOLID abstract factory:
public interface BFactory {
B Create(string bparam);
}
public class BFactoryUnity : BFactory {
private IUnityContainer container;
public BFactoryUnity(IUnityContainer container) {
this.container = container;
}
public B Create(String bParam) {
var b = new B(bParam);
container.BuildUp(b);
return b;
}
}
So you can register:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA")
.RegisterType<BFactory, BFactoryUnity>();
Now the client can resolve only the factory and use it:
var bFactory = _container.Resolve<BFactory>();
var b = bFactory.Create();
Now, in a big application you will need a lot of similar factories. To avoid the boilerplate code of abstract factories and implementations you can find in the web some implementation of automatic abstract factory extensions.
I have the following code in a library:
public interface IFirst { }
public interface ISecond { }
public class Second : ISecond
{
public Second(IFirst injectedFirstService)
{
}
}
Now, I would like to specify in a MEF container that the ISecond interface should be provided to other parts with an instance of Second, built with dependency injection.
I would also like to do it in a way that does not force me to put an attribute inside of the library class (that is, no ImportingConstructor in the Second class).
I know of the following solutions:
Use a subclass of second or a class that decorates Second but still implements the same ISecond interface, but with the appropriate MEF attributes. These types could then be exposed in a composition catalog.
Write a MEF attributed part that basically translates the constructor imports and the instance export as property imports and exports, in the following way, to be put in a CompositionBatch instance:
public class SecondExporter
{
[Import] IFirst First { get; set; }
[Export] ISecond Second { get { return new Second(First); } }
}
What else can I do?
I have two classes, one which sets up the container by registering types and one which contains a static property which I want to inject into. My issue is the property is never set by injection so when I call a method on it, the property is always null.
public class ClassOne
{
public void Method()
{
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
}
}
public static class ClassTwo
{
[Dependency]
public static IClass SomeProperty { get; set; }
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
If I remove the Dependency attribute and in ClassOne do a simple
ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
it works fine, but I want to know if it is possible to do this without explicitly assigning a value to the property (i.e. can the container inject through attributes)?
Edit:
Thanks. I have removed the static declaration from ClassTwo and in ClassOne added RegisterType and Resolve for ClassTwo and also added InjectionProperty:
Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));
but it still does not work :S
Edited after considering comments:
There are a variety of reasons why at times you still want or need to use static classes instead of cascading everything through Unity.
If the static class has a dependency on another class that you would want to be configurable/exchangeable via your Unity configuration I prefer using a factory pattern as described at How to resolve dependency in static class with Unity? or simply assigning a function to resolve the dependency when needed, rather than referencing the Container from within the static class. One advantage being that all your Unity configuration can be in the same place.
In your case it could look like this:
public static class ClassTwo
{
private static IClass _someProperty;
public static Func<IClass> ResolveProperty { private get; set; }
private static IClass SomeProperty
{
get { return _someProperty ?? (_someProperty = ResolveProperty()); }
}
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
And in your Unity configuration add this:
ClassTwo.ResolveProperty = () => container.Resolve<IClass>();
Unity inject dependencies when the class is resolved through Unity. A static class can not be created, so Unity can not inject dependencies.
Instead of having a Static class, use Unity to resolve a pseudo-singleton class (ContainerControlledLifetimeManager) of ClassTwo. This way Unity injects IClass to ClassTwo when ClassTwo is created (resolved throug Unity container) and, as is configured as singleton, you always have the same instace of ClassTwo in the whole lifecicle of your application.
You must resolve ClassTwo through Unity.
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
Container.RegisterType<InterfaceImplemetedByClassTwo, ClassTwo>();
//Simple example. Don't forget to use ContainerControlledLifetimeManager for ClassTwo to simulate sigleton.
And when you need ClassTwo:
Container.Resolve<InterfaceImplemetedByClassTwo>
Having the config in ClassTwo:
public class ClassTwo : InterfaceImplemetedByClassTwo
{
[Dependency("ImplOne")] //inject ClassImplOne
public IClass SomeProperty { get; set; }
BUT this is not a great solution, I think your problem is with the phylosophy of DI. You need to cascade dependencies from the top layer classes of your app. Resolve the top layer classes in a explicit way. (Container.Resolve) and dependecies injection cascade down thanks to the magic of Unity. When 2 classes (top layer or not) need to use the same instance of ClassTwo Unity do the dirty work if you configured ClassTwo with ContainerControlledLifetimeManager.
In other words, you don't need static class, you inject the same instance of a class in other classes than need it.
I currently have a main class which might call another class which might call 2 or 3 others. The main class might create a Windows form as well.
So at the moment we might have:
public class MainClass
{
...
AnotherClass = new AnotherClass();
fmMain myForm = new fmMain();
}
public class AnotherClass
{
...
DatabaseClass dbClass = new DatabaseClass();
FileClass fClass = new FileClass();
}
As I see it, after refactoring and putting in constructor interface dependencies I can use an IOC container.
The problem is my entry point is the main class so all I can see to do is have all the dependencies in the main class constructor and then pass these down into the other classes and forms.
The issue is this could get very messy and the main class might have 10 dependencies most of which used in other classes. Is there an alternative?
Let the IoC container to do this.
Register AnotherClass as a dependency and then resolve it directly referring to container instance.
Dependencies should be defined locally to where they are required i.e. the dependencies should be defined on the constructors of the types, then use an IoC container to resolve all types. In this way the IoC takes care of "passing these down into the other classes and forms". When using an IoC container avoid using "new" whenever possible, and instead use the container to create instances. It will handle creation and injection of dependencies for you.
For example (using Ninject), the following demonstrates a Form which defines its own dependencies. The container will supply and inject all dependencies recursively when used to resolve an instance of the ProductForm.
Dependencies do not need to be injected into the entry-point class, but are specified as bindings in a module and then injected by the container when types such as Forms are resolved.
public class Program
{
public Program()
{
IKernel kernel = new StandardKernel(new MainModule());
Form form = kernel.Get<ProductForm>();
form.Show();
}
}
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<ProductForm>().ToSelf();
Bind<IProductService>().To<ProductService>();
Bind<IProductDb>().To<IProductDb>();
}
}
internal class ProductForm : Form
{
private readonly IProductService _productService;
public ProductForm(IProductService productService)
{
_productService = productService;
}
}
internal interface IProductService {}
internal class ProductService : IProductService
{
private readonly IProductDb _productDb;
public ProductService(IProductDb productDb)
{
_productDb = productDb;
}
}
internal interface IProductDb {}
internal class ProductDb : IProductDb {}
It sounds like your Main class is your Composition Root. That's fine - it's not going to become messy if that's the only thing it does. This should be its single responsibility. In other words: your application entry point should be a Humble Object.