Unity Static Property Injection - c#

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.

Related

How to resolve concrete classes in Unity Dependency Injection

I seem to be stumped on how to implemented the strategy pattern with a DI container.
I have a strategy interface:
public interface IUserCompaniesInviteStrategy
{
bool InviteUserToCompany(UserCompaniesInviteRequest userCompaniesInviteRequest);
}
and a couple of concrete classes:
public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy
public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy
How do I wire up Unity with this?
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>();
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>();
obviously doesn't work...
I tried:
container.RegisterType<IUserCompaniesInviteStrategy<ConcreteExistingUserInviteStrategy>, ConcreteExistingUserInviteStrategy>();
container.RegisterType<IUserCompaniesInviteStrategy<ConcreteNewUserInviteStrategy>, ConcreteNewUserInviteStrategy>();
with
public interface IUserCompaniesInviteStrategy<T>
That doesn't seem to work.
I think what I'd like to do here is use named types, so like:
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("1");
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("2");
However, I have constructor injection setup and using container.resolve isn't a good option for me because of n-tier architecture and chaining dependencies I'd have to resolve.
How can I inject a named type into a constructor? Is there a better way to do what I'm trying to do? (Create an interface that resolves to two concrete strategies)
Update:
I took a look at With Unity how do I inject a named dependency into a constructor? . The accepted answer won't work because I don't have a dependency on Unity in my domain, nor do I want it. I tried the StrategyResolver, but I'm getting:
An error occurred when trying to create a controller of type 'UserController'. Make sure that the controller has a parameterless public constructor.
That is indicative of a DI problem.
The StrategyResolver and IStrategyResolver are the same as in the example:
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
public interface IStrategyResolver
{
T Resolve<T>(string namedStrategy);
}
My config:
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteExistingUserInviteStrategy>("ExistingUser");
container.RegisterType<IUserCompaniesInviteStrategy, ConcreteNewUserInviteStrategy>("NewUser");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<IUserFactory, UserFactory>();
Concretes:
public class ConcreteExistingUserInviteStrategy : IUserCompaniesInviteStrategy
public class ConcreteNewUserInviteStrategy : IUserCompaniesInviteStrategy
And then I call it like:
_strategyResolver.Resolve<IUserCompaniesInviteStrategy>("ExistingUser");
Not sure what's wrong with it.

Do I pass singletons as parameters or do I manually resolve them? (Unity DI)

I am using unity mvc4 package, it is auto injecting into my controllers fine. But now I am manually doing other parts of my application, helpers etc.
How can I access the singletons within the container from other classes?
How do I call MethodWithDependency(param) on my instance of MyClass2? Am I supposed to do the below? It looks far too messy.
public class MyClass1
{
public void Main()
{
var myObject2 = container.Resolve<MyClass2>;
var someObject = container.Resolve<SomeClass>;
myObject2.MethodWithDependency(someObject);
}
}
public class MyClass2
{
public void MethodWithDependency(SomeClass someObject)
{
}
}
Each object that needs its dependencies resolved can potentially have them resolved by the container. To not to spoil your code with containers, you create local factories and implement specific factory providers elsewhere, in the Composition Root which is the only place in your application where container is created and used directly.
This requires discipline, however you are able to structure your code so that there is no explicit reference to the container except for the Composition Root and still container does the job.
I wrote a tutorial on that once, it is too long to quote it here:
http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html
Answering your specific question: to have singletons you just use the ContainerControllerLifetimeManager as the parameter to the register method.
http://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx
Create MyClass2 so that it accepts SomeClass as an argument in the constructor (you are injecting the SomeClass dependency into your MyClass2 object).
Then, you can register your Instances with the Container. At that point, when you resolve your MyClass2 object, your SomeClass object will also be resolved and injected into MyClass2.
Beautiful, huh?
The Code
public class MyClass1
{
private UnityContainer _container;
public void Main()
{
this.RegisterContainer();
// Since SomeClass was registered, when you resolve MyClass2, it will
// magically resolve an instance of SomeClass that the MyClass2
// constructor needs.
var myObject2 = this._container.Resolve<MyClass2>;
myObject2.MethodWithDependency();
}
private void RegisterContainer()
{
// Here, initialize your Container then register your singletons.
this._container = new UnityContainer();
// Do not use container.RegisterType<>()....
// RegisterInstance, by default, implements a singleton behavior.
this._container.RegisterInstance<SomeClass>();
this._container.RegisterInstance<MyClass2>();
}
}
public class MyClass2
{
private SomeClass _someClass;
// You are injecting the SomeClass dependency into your MyClass2 class.
// Hence the name — Dependency Injection.
public MyClass2(SomeClass someClass)
{
this._someClass = someClass;
}
public void MethodWithDependency()
{
// use your _someClass object.
this._someClass.DoSomething();
}
}

Auto-wiring property injection

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...

Initialising fields with initial values with Ninject

I'm currently trying to work out how to set the initial values for some fields using Ninject.
I have something like this:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
}
public void DoAThing()
{
_something.DoSomething();
}
}
My dilemma comes about in the setting of _something to an initial value, given I don't want the class to know anything about which default implementation of ISomething to use, is there a way of achieving this in Ninject?
I should add that passing the initial values in via the constructor is not an option.
I should also add that this is in a class-library, so any information on how and when the setup of the kernel & injection should take place would be great :)
Elaboration: It seems that people could be getting confused, I am not trying to get an ISomething into the class (it isn't a dependency), rather, the default implementation of ISomething is the dependency, this is why I went for the service-locator pattern, for actual dependencies I would of course have them in the constructor.
Thanks.
Yes, it's not very good to have highly coupled classes, thus depending on abstractions is a good choice. But hiding your dependencies is not very good solution. Make them visible to clients of your class, and use dependency injection to provide concrete implementations of dependencies to your class:
public class SomeClass
{
private ISomething _something;
public SomeClass(ISomething something, string someParam)
{
_something = something;
}
public void DoAThing()
{
_something.DoSomething();
}
}
Also consider to create factory, which will provide default implementation of ISomething to created SomeClass objects.
In the end I decided to go with a static IOC access class to allow my code to gain access to the core Ninject Kernel used by the class library for the main injection.
So:
internal static class IOC
{
private static readonly IKernel _kernel;
static IOC()
{
_kernel = new StandardKernel(new IModule[] {
new SomethingModule(),
});
}
static T Get<T>()
{
return _kernel.Get<T>();
}
}
internal sealed class SomethingModule : StandardModule
{
public override void Load()
{
Bind<ISomething>().To<ConcreteSomething>(
new ConstructorParam("arg", "value"));
}
}
Then in my previous class:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
_something = IOC.Get<ISomething>();
}
public void DoAThing()
{
_something.DoSomething();
}
}
Now I can get concrete implementations and even have them initialised with default values to boot!
The way of getting the concrete classes initialised with default values is a little flimsy, but I'm sure there are smarter ways of achieving this in Ninject, but it does appear that a hybrid solution of service-locator-esque code and Ninject works quite well!
BTW I believe you could also have multiple IOC containers in differing scopes (themselves passed along via Ninject :P) to prevent creating a behemoth "everything everywhere" kernel.
Hope this helped someone!

Interface dependency hierarchy

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.

Categories