i am new in Dependency injection. i just got familiar how to implement dependency injection with Interface injection but we know that Dependency injection can be implemented with three way or may be more and those are :-
Interface injection: The service provides an interface which consumers must implement. The interface exposes specific behaviors at run time.
Setter injection: The dependent object exposes a “setter” method to inject the dependency.
Constructor injection: Dependencies are injected through the class constructor
so i am looking for few sample code which can help me to understand how to implement Dependency injection using either Setter injection or Constructor injection using unity. any help with small small code for different way of implementing dependency injection will be appreciated.
i know only Interface injection using unity. here is my code which works fine using Interface injection with unity.
public interface ILogger
{
void Write(string message);
}
We have define three classes as follows.
public class FileLogger : ILogger
{
public void Write(string message)
{
//Do somthing
}
}
public class SQLLogger : ILogger
{
public void Write(string message)
{
//Do somthing
}
}
public class WindowsEventLogger : ILogger
{
public void Write(string message)
{
//Do somthing
}
}
Need to register and map these classes with interface in configuration file (i.e. app.config).
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias type="UnityTest.ILogger, UnityTest" alias="ILogger" />
<namespace name="UnityTest"/>
<container>
<register mapTo="UnityTest.FileLogger, UnityTest" name="MyFileLogger" type="ILogger"/>
<register mapTo="UnityTest.SQLLogger, UnityTest" name="MySQLLogger" type="ILogger"/>
<register mapTo="UnityTest.WindowsEventLogger, UnityTest" name="MyWindowsEventLogger" type="ILogger"/>
</container>
</unity>
Note: name attribute is important in register tag.
Finally we have to use this map into our code. So, we have to know that for which one is preferable for specific country.
A dictionary object can be use to keep this mapping as follows.
IDictionary<string, string> loggers = new Dictionary<string, string>();
loggers.Add("USA", "MyFileLogger");
loggers.Add("GBR", "MySQLLogger");
loggers.Add("IN", "MyWindowsEventLogger");
You can populate it from database, xml or another source, and now it's time to call the Write method.
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
ILogger logger = container.Resolve<ILogger>(loggers[objUser.countryCode]);
logger.Write("Hello World");
New question
I found a sample code for construction injection with unity but still one thing is not clear. Here is the code.
public class CustomerService
{
public CustomerService(LoggingService myServiceInstance)
{
// work with the dependent instance
myServiceInstance.WriteToLog("SomeValue");
}
}
IUnityContainer uContainer = new UnityContainer();
CustomerService myInstance = uContainer.Resolve<CustomerService>();
When we write uContainer.Resolve<CustomerService>(); then we are not sending any instance of LoggingService class then how we can create instance of CustomerService class because it's constructor require instance of LoggingService.
This area is not clear. Please explain to me how it works.
Another question is [Dependency] attribute: what it does, and when a method needs to be decorated with the [Dependency] attribute.
With your code as a base.
if you have some class that depends on ILogger, and you have a default registration for ILogger (a registration without name)
IUnityContainer container = new UnityContainer();
//fixed
//by default RegisterType will create new instance of the type every time
//the container resolves the dependancy
container.RegisterType<ILogger,SomeLoggerImplementation>();
container.RegisterType<Foo>();
container.RegisterType<Bar>();
//will create a new instance of SomeLoggerImplementation using a default ctor, pass it to the constructor of Foo and return the instance of Foo
//if SomeLoggerImplementation has some other dependancies they can be registered in the container too!
var foo = container.Resolve<Foo>();
//will create a new instance of SomeLoggerImplementation using a default ctor, create a new instance of Bar,
//Set the value of the Property Logger (but not the Logger2), and return the instance of Bar
var bar = container.Resolve<Bar>();
//Constructor injection
public class Foo
{
private ILogger _logger;
public Foo(ILogger logger)
{
//if Foo is resolved from the container , the value for the logger parameter will be provided from the container
_logger = logger;
}
}
//property injection
public class Bar
{
//If Bar is resolvced from the container the value for the Logger property will also be provided from the container
[Dependency]
public ILogger Logger { get; set; }
//this will not be injected
public ILogger Logger2 { get; set; }
public Bar()
{
}
}
First register the classes to be solved to unity (in this case register Test class to unity). When you try to resolve an instance of Test class using unity, it will resolve ILogger too. You may refer to injection attributes from msdn
setter injection;
public class Test : ITest
{
[Dependency("MyFileLogger")]
public ILogger Logger
{
get { return iLogger; }
set { iLogger = value; }
}
}
constructor injection;
public class Test : ITest
{
public Test([Dependency("MyFileLogger")] ILogger logger)
{
//// you will have an instance of MyFileLogger
}
}
For the second part of your question, since LoggingService is also registered to unity, when CustomerService is tried to be resolved, it will use constructor injection to resolve the LoggingService parameter. In other words, when container tries to resolve CustomerService; it understands that LoggingService is needed to resolve it. Then it first resolves LoggingService parameter and then tries to resolve CustomerService.
Related
I have many projects :
Service.DataAccess
Service.DataAccess.Interfaces
Service.Main
Service.Factory
Service.DataAccess have a reference to Service.DataAccess.Interfaces.
Service.Main have a reference to Service.DataAccess.Interfaces and to Service.Factory
In Service.Main I have :
var instance = Service.Factory.ObjectFactory.Resolve<Service.DataAccess.Interfaces.IDataAccessLayer>();
In Service.Factory :
public void InitContainer(IUnityContainer container)
{
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container); //Exception here!
}
In my configuration file :
<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="Service.DataAccess.Interfaces.IDataAccessLayer, Service.DataAccess.Interfaces"
mapTo="Service.DataAccess.DataAccessLayer, Service.DataAccess" />
</container>
</unity>
But I have a exception at runtime in InitContainer method :
The type name or alias Service.DataAccess.Interfaces.IDataAccessLayer could not be resolved. Please check your configuration file and verify this type name.
I don't understand
Thank's!
Your container need to be able to access the constructor of your implementation. So it needs access to a public constructor of the class Service.DataAccess.DataAccessLayer, which means that your Service.Factory needs to reference Service.DataAccess. But also Service.DataAccess.Interfaces, because otherwise it will not find the interface.
You may also separate it into several steps, and let each library take care of their own registrations.
Main doesn't necessarily need have a reference to Service.DataAccess if it goes through Service.Factory to create it. Let's take a very simple example.
In your Main:
var container = new UnityContainer();
container.Register<IFactory, SomeFactory>(); // Factory is a class in Service.Factory.
// Let your factory project take care of it's registrations as well.
Service.Factory.Startup.InitContainer(container);
var factory = container.Resolve<IFactory>();
Service.DataAccess.Interfaces.IDataInterface foo = factory.Create();
In your Service.Factory:
// Class for initiating registrations.
public static class Startup
{
public static InitContainer(IUnityContainer container)
{
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
}
}
// Some example class...
public class SomeFactory : IFactory
{
private readonly IUnityContainer _container;
public SomeFactory(IUnityContainer container)
{
_container = container;
}
public IDataInterface Create()
{
// return the implementation.
return _container.Resolve<IDataInterface>();
}
}
Note that the SomeFactory uses the ServiceLocator anti-pattern. But it's mostly a proof-of-concept to show how it could work. It's a way to let Service.Main only reference the interfaces, but not the concrete classes. Service.Factory, however, needs to reference both.
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 have the IRespository registered twice (with names) in the following code:
// Setup the Client Repository
IOC.Container.RegisterType<ClientEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Client", new InjectionConstructor(typeof(ClientEntities)));
// Setup the Customer Repository
IOC.Container.RegisterType<CustomerEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Customer", new InjectionConstructor(typeof(CustomerEntities)));
IOC.Container.RegisterType<IClientModel, ClientModel>();
IOC.Container.RegisterType<ICustomerModel, CustomerModel>();
But then when I want to resolve this (to use the IRepository) I have to do a manual resolve like this:
public ClientModel(IUnityContainer container)
{
this.dataAccess = container.Resolve<IRepository>(Client);
.....
}
What I would like to do is to have it resolved in the constructor (just like IUnityContainer). I need some way to say which named type to resolve to.
Something like this: (NOTE: Not real code)
public ClientModel([NamedDependancy("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
Is there a way to make my fake code work?
You can configure dependencies with or without names in the API, attributes, or via the config file. You didn't mention XML above, so I'll assume you're using the API.
To tell the container to resolve a named dependency, you'll need to use an InjectionParameter object. For your ClientModel example, do this:
container.RegisterType<IClientModel, ClientModel>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<IRepository>("Client") // Resolve parameter of type IRepository using name "Client"
)
);
This tells the container "When resolving ClientModel, call the constructor that takes a single IRepository parameter. When resolving that parameter, resolve with the name 'Client' in addition to the type."
If you wanted to use attributes, your example almost works, you just need to change the attribute name:
public ClientModel([Dependency("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
This is a very late response but the question still shows up in Google.
So anyways, 5 years later...
I have a pretty simple approach. Usually when you need to use "named dependency" it's because you're trying to implement some kind of strategy pattern. In that case, I simply create a level of indirection between Unity and the rest of my code called the StrategyResolver to not be directly depending on Unity.
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);
}
}
Usage:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Registration:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Now, the nice thing about this is that I will never have to touch the StrategyResolver ever again when adding new strategies in the future.
It's very simple. Very clean and I kept the dependency on Unity to a strict minimum. The only time I would have touch the StrategyResolver is if I decide to change container technology which is very unlikely to happen.
Hope this helps!
Edit: I don't really like the accepted answer because when you use the Dependency attribute in your service's constructor you actually have a hard dependency on Unity. The Dependency attribute is part of the Unity library. At that point you might as well pass an IUnityContainer dependency everywhere.
I prefer having my service classes depend on objects that I completely own instead of having a hard dependency on an external library all over the place. Also using Dependency attribute makes the constructors signatures less clean and simple.
Furthermore, this technique allows to resolve named dependencies at runtime without having to hardcode the named dependencies in the constructor, in the application configuration file or use InjectionParameter which are all methods that require to know what named dependency to use at design time.
Edit (2016-09-19):
For those that might wonder, the container will know to pass itself when you are requesting IUnityContainer as dependency, as shown in the StrategyResolver constructor signature.
Edit (2018-10-20):
Here's another way, simply using a factory:
public class SomeStrategyFactory : ISomeStrategyFactory
{
private IStrategy _stratA;
private IStrategy _stratB;
public SomeFactory(IStrategyA stratA, IStrategyB stratB)
{
_stratA = stratA;
_stratB = stratB;
}
public IStrategy GetStrategy(string namedStrategy){
if (namedStrategy == "A") return _stratA;
if (namedStrategy == "B") return _stratB;
}
}
public interface IStrategy {
void Execute();
}
public interface IStrategyA : IStrategy {}
public interface IStrategyB : IStrategy {}
public class StrategyA : IStrategyA {
public void Execute(){}
}
public class StrategyB : IStrategyB {
public void Execute() {}
}
Usage:
public class SomeClass : ISomeClass
{
public SomeClass(ISomeStrategyFactory strategyFactory){
IStrategy strat = strategyFactory.GetStrategy("HelloStrategy");
strat.Execute();
}
}
Registration:
container.RegisterType<ISomeStrategyFactory, SomeStrategyFactory>();
container.RegisterType<IStrategyA, StrategyA>();
container.RegisterType<IStrategyB, StrategyB>();
container.RegisterType<ISomeClass, SomeClass>();
This 2nd suggestion is the same thing but using the factory design pattern.
Hope this helps!
You should be able to use ParameterOverrides
var repository = IOC.Container.Resolve<IRepository>("Client");
var clientModel = IOC.Container.Resolve<ClientModel>(new ParameterOverrides<ClientModel> { {"dataAccess", repository } } );
edit:
I'm not sure why you're passing around the UnityContainer - personally, we inject our dependencies into the constructor themselves (which is "normal" from what I've seen). But regardless, you can specify a name in your RegisterType and Resolve methods.
IOC.Container.RegisterType<IRepository, GenericRepository>("Client");
IOC.Container.Resolve<IRepository>("Client");
and it will give you the type you registered for that name.
Don't do this - just create a class ClientRepository : GenericRepository { } and utilise the Type system.
Ultimately this has to do with setting up log4Net but generically the problem is not logging specific.
Generically what I am trying to figure out is how to do, in Microsoft Unity 2.0, something equivalent to what one gets with the Castle.Facilities.Logging.LoggingFacility. Namely the ability to declare a dependency on a logger and have the logger initialized with the Type of the object into which it is being injected.
In the spirit of a test is worth a thousand words, here is what I need:
class Logger_IOC_Tests
{
//[Test]
public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
{
var container = new UnityContainer();
/* Configuration Magic probably involiving registering either
* a custom IDependencyResolverPolicy or BuilderStrategy
* goes here...
*/
container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
var user = container.Resolve<LoggerUser>();
Assert.True(user.Logger.GetUserType() == user.GetType());
}
}
interface ILogger
{
Type GetUserType();
}
class Logger : ILogger
{
private readonly Type _type;
public Logger(Type type)
{
_type = type;
}
public Type GetUserType()
{
return _type;
}
}
class LoggerUser
{
public readonly ILogger Logger;
public LoggerUser(ILogger logger)
{
Logger = logger;
}
}
I don't know if this what you are looking for, but I saw it a few months ago and was reminded of it when I saw your question. I have not used Unity, so I can't really compare what you have posted with what is at the link. Hopefully it will be useful to you:
http://davidkeaveny.blogspot.com/2011/03/unity-and-log4net.html
I've been trying to achieve the same result of being able to insert correctly configured ILog instances into a dependency using constructor injection with Unity.
In the end, I wrote my own "log4net" unity extension to do exactly this (in part inspired by a blog post that another answerer, Kenneth Baltrinic, wrote).
This allows you to register the extension once with Unity:
var container = new UnityContainer();
container.AddNewExtension<Log4NetExtension>();
and then have the correct ILog logger instance passed in:
public class MyClass
{
private readonly ILog logger;
public MyClass(ILog logger)
{
this.logger = logger;
}
}
The extension can be found here:
https://github.com/roblevine/UnityLoggingExtensions
More info here: http://blog.roblevine.co.uk/net/using-log4net-with-unity/
EDIT this is now available as a NuGet package
After hours of digging around in the Unity source code, I came up with the following solution. However, I would prefer to find a way to set the appropriate dependency resolver based on the type being resolved rather than overriding the default constructor selector policy. For one, because I previously overrode the default constructor selector for other purposes. For another, this solution only handles dependencies that are injected via constructor. For full coverage one would have to override the default property and method selectors as well I presume. For myself, I only need constructors.
class Logger_IOC_Tests
{
[Test]
public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
{
var container = new UnityContainer();
container.AddNewExtension<LoggingExtension>();
container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
var user = container.Resolve<LoggerUser>();
Assert.True(user.Logger.GetUserType() == user.GetType());
}
}
class LoggingExtension : UnityContainerExtension
{
protected override void Initialize()
{
Context.Policies.SetDefault(typeof(IConstructorSelectorPolicy), new LoggingConstructorSelectorPolicy());
}
}
public class LoggingConstructorSelectorPolicy : DefaultUnityConstructorSelectorPolicy
{
protected override IDependencyResolverPolicy CreateResolver(ParameterInfo parameter)
{
return parameter.ParameterType == typeof(ILogger)
? new LoggerResolverPolicy(parameter.Member.DeclaringType)
: base.CreateResolver(parameter);
}
}
class LoggerResolverPolicy : IDependencyResolverPolicy
{
private readonly Type _dependantType;
public LoggerResolverPolicy(Type dependantType)
{
_dependantType = dependantType;
}
public object Resolve(IBuilderContext context)
{
return new Logger(_dependantType);
}
}
The above extension works well but more configuration information is needed for MVC5 users. Here are the steps using unity.
Add the following line to the top of your startup.cs class above the namespace.
[assembly: log4net.Config.XmlConfigurator(ConfigFile ="Web.config", Watch = true)]
In your global.asax application_startup method add the following information:
log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
The rest of the configuration to the unity container should be as is:
container.AddNewExtension<Log4NetExtension>();
Ensure you have an appender added to your web.config. That should be about it to get this working correctly. Good Luck
With Unity 5 and above, you can now use Unity's own Log4Net extension from https://github.com/unitycontainer/log4net.
All you have to do is install the Nuget and add the extension to your container:
container.AddNewExtension<Log4NetExtension>();
And it will work automatically with any classes that use ILog as a dependency.
You can use the following code to inject Log4Net
log4net.Config.BasicConfigurator.Configure();
container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));
typeof(Program) is used since I'm registering in program class. Use can use the class name or this keyword
Then you can inject ILog into the class
public class MyClass
{
private readonly ILog logger;
public MyClass(ILog logger)
{
this.logger = logger;
}
}