C#, Castle Windsor and The Composite design pattern - c#

I have designed a telemetry logger for few separate platforms using the composite pattern
public interface ILogger
{
void Log();
}
public class A : ILogger
{
public void Log(...);
}
public class B : ILogger
{
public void Log(...);
}
public class Many : ILogger
{
private readonly List<ILogger> m_loggers;
public Many(IEnumerable<ILogger> loggers)
{
m_loggers = loggers.ToList();
}
public void Log()
{
m_loggers.ForEach(c => c.Log());
}
}
Now i want to be able to get an instance of "Many" from Windsor container
but have encountered a few problems:
if all ILoggers are in the container how can i make sure i get the "Many" implementation and not "A" or "B" ?
I tried following this example
Castle Windsor: How do I inject all implementations of interface into a ctor?
and use container.Kernel.Resolver.AddSubResolver(new
CollectionResolver(container.Kernel));
to register a class with IEnumerable dependancy but if
that class also implements IComponent wont it create a circular
dependency ?
Is what I'm attempting even possible ?

First of all this is Composite Design Pattern not Component.
The way you do it in Castle Windsor in your case should look like this
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(Component.For<ILogger>().ImplementedBy<Many>());
container.Register(Component.For<ILogger>().ImplementedBy<A>());
container.Register(Component.For<ILogger>().ImplementedBy<B>());
This works because Castle Windsor have internal understanding of patterns like Composite or Decorator so no circular dependency will be created in this case. Just bare in mind that order of registration is important in this case.
More on registering different patterns in Castle Windsor can be found here.

Is it possible with a factory method in the container registration?
var container = new Castle.Windsor.WindsorContainer();
container.Register(Component.For<A>());
container.Register(Component.For<B>());
container.Register(Component.For<ILogger>()
.UsingFactoryMethod(k => new Many(k.Resolve<A>(), k.Resolve<B>())));
var logger = container.Resolve<ILogger>();
After changing:
public Many(params ILogger [] loggers)
{
m_loggers = loggers.ToList();
}
Limited knowledge of the Windsor Container lead me to this, there is probably an improvement to this along the same lines of using a factory to initialize your object. The important thing is the configuration is within the container (Even if it is a little verbose)

Related

Determining which implementation to inject at runtime using .NET Core dependency injection

I have three types of users in my application, let's say Type1, Type2 and Type3.
Then i want to create one service implementation for each type, let's say i have a service to get photos, i would have three services : Type1PhotosService, Type2PhotosService and Type3PhotosService, each of them implementing IPhotosService.
In the web api, i would inject IPhotosService :
IPhotosService _service;
public PhotosController(IPhotosService service){
_service = service;
}
The web api uses token authentication with claims. So what i want to achieve, is for each user, depending on the claim he has : type1 or type2 or type3, the correct implementation of the service will be automatically injected rather than injecting a single service in the startup file.
What i want to avoid, is having one service, with a bunch of switch and if statements to return the correct data depending on user type and the roles he has.
EDIT:
some comments were wondering what's the point of three implementations, so here are more details to give it a little more sense.
The service is a job finder service, and the application has three different profiles : candidate, employer and administration. Each of these profiles need a proper implementation. So rather than having three methods GetCandidateJobs, GetEmployerJobs and GetAdministrationJobs inside the same service and switch on the user type, i preferred to have one implementation per profile type, then depending on the profile type, use the correct implementation.
Without Using a Separate IoC Container
Here's an approach that's way easier than configuring your app to use another IoC container and then configuring that container. After working through this with Windsor this solution seems a whole lot easier.
This approach is simplest if you can use a singleton instance of each service implementation.
We'll start with an interface, some implementations, and the factory we can inject which will return an implementation selected at runtime based on some input.
public interface ICustomService { }
public class CustomServiceOne : ICustomService { }
public class CustomServiceTwo : ICustomService { }
public class CustomServiceThree : ICustomService { }
public interface ICustomServiceFactory
{
ICustomService Create(string input);
}
Here's a really crude implementation of the factory. (Didn't use string constants, or polish it at all.)
public class CustomServiceFactory : ICustomServiceFactory
{
private readonly Dictionary<string, ICustomService> _services
= new Dictionary<string, ICustomService>(StringComparer.OrdinalIgnoreCase);
public CustomServiceFactory(IServiceProvider serviceProvider)
{
_services.Add("TypeOne", serviceProvider.GetService<CustomServiceOne>());
_services.Add("TypeTwo", serviceProvider.GetService<CustomServiceTwo>());
_services.Add("TypeThree", serviceProvider.GetService<CustomServiceThree>());
}
public ICustomService Create(string input)
{
return _services.ContainsKey(input) ? _services[input] : _services["TypeOne"];
}
}
This assumes that you've already registered CustomServiceOne, CustomServiceTwo, etc. with the IServiceCollection. They would not be registered as interface implementations, since that's not how we're resolving them. This class will simply resolve each one and put them in a dictionary so that you can retrieve them by name.
In this case the factory method takes a string, but you could inspect any type or multiple arguments to determine which implementation to return. Even the use of a string as the dictionary key is arbitrary. And, just as an example, I provided fallback behavior to return some default implementation. It might make more sense to throw an exception instead if you can't determine the right implementation to return.
Another alternative, depending on your needs, would be to resolve the implementation within the factory when it's requested. To the extent possible I try to keep most classes stateless so that I can resolve and reuse a single instance.
To register the factory with the IServiceCollection at startup we would do this:
services.AddSingleton<ICustomServiceFactory>(provider =>
new CustomServiceFactory(provider));
The IServiceProvider will be injected into the factory when the factory is resolved, and then the factory will use it to resolve the service.
Here's the corresponding unit tests. The test method is the identical to the one used in the Windsor answer, which "proves" that we can transparently replace one factory implementation with another and change other stuff in the composition root without breaking stuff.
public class Tests
{
private IServiceProvider _serviceProvider;
[SetUp]
public void Setup()
{
var services = new ServiceCollection();
services.AddSingleton<CustomServiceOne>();
services.AddSingleton<CustomServiceTwo>();
services.AddSingleton<CustomServiceThree>();
services.AddSingleton<ICustomServiceFactory>(provider =>
new CustomServiceFactory(provider));
_serviceProvider = services.BuildServiceProvider();
}
[TestCase("TypeOne", typeof(CustomServiceOne))]
[TestCase("TypeTwo", typeof(CustomServiceTwo))]
[TestCase("TYPEThree", typeof(CustomServiceThree))]
[TestCase("unknown", typeof(CustomServiceOne))]
public void FactoryReturnsExpectedService(string input, Type expectedType)
{
var factory = _serviceProvider.GetService<ICustomServiceFactory>();
var service = factory.Create(input);
Assert.IsInstanceOf(expectedType, service);
}
}
As in the Windsor example, this is written to avoid any reference to the container outside of the composition root. If a class depends on ICustomServiceFactory and ICustomService you could switch between this implementation, the Windsor implementation, or any other implementation of the factory.
Using Windsor
I'm going to sidestep the questions about whether or not this makes sense in this case and just attempt to answer the question as asked:
.NET Core's IoC container isn't built particularly well for this sort of scenario. (They acknowledge this in their documentation.) You can work around it by adding another IoC container like Windsor.
The implementation ended up looking way more complicated than I would have liked, but once you get past the setup it's not bad and you get access to Windsor's features. I'm going to provide another answer that doesn't include Windsor. I had to do all of this work to see that I probably like the other approach better.
In your project, add the Castle.Windsor.MsDependencyInjection NuGet package.
Interfaces and Implementations for Testing
For testing, I added some interfaces and implementations:
public interface ICustomService { }
public interface IRegisteredWithServiceCollection { }
public class CustomServiceOne : ICustomService { }
public class CustomServiceTwo : ICustomService { }
public class CustomServiceThree : ICustomService { }
public class RegisteredWithServiceCollection : IRegisteredWithServiceCollection { }
The intent is to create a factory that will select and return an implementation of ICustomService using some runtime input.
Here's an interface which will serve as a factory. This is what we can inject into a class and call at runtime to get an implementation of ICustomService:
public interface ICustomServiceFactory
{
ICustomService Create(string input);
}
Configure the Windsor Container
Next is a class which will configure an IWindsorContainer to resolve dependencies:
public class WindsorConfiguration : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<ICustomService, CustomServiceOne>().Named("TypeOne"),
Component.For<ICustomService, CustomServiceTwo>().Named("TypeTwo"),
Component.For<ICustomService, CustomServiceThree>().Named("TypeThree"),
Component.For<ICustomService, CustomServiceOne>().IsDefault(),
Component.For<ICustomServiceFactory>().AsFactory(new CustomServiceSelector())
);
}
}
public class CustomServiceSelector : DefaultTypedFactoryComponentSelector
{
public CustomServiceSelector()
: base(fallbackToResolveByTypeIfNameNotFound: true) { }
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return (string) arguments[0];
}
}
Here's what's going on in here:
The TypedFactoryFacility will enable us to use Windsor's typed factories. It will create an implementation of our factory interface for us.
We're registering three implementations of ICustomService. Because we're registering more than one implementation, each must have a name. When we resolve ICustomService we can specify a name, and it will resolve the type according to that string.
For illustration I registered another implementation of ICustomService without a name. That will enable us to resolve a default implementation if we try to resolve using an unrecognized name. (Some alternatives are just throwing an exception, or returning a "null" instance of ICustomService or creating a class like UnknownCustomService that throws an exception.)
Component.For<ICustomServiceFactory>().AsFactory(new CustomServiceSelector()) tells the container to create a proxy class to implement ICustomServiceFactory. (More on that in their documentation.)
CustomServiceSelector is what takes the argument passed to the factory's Create method and returns the component name (TypeOne, TypeTwo, etc.) that will be used to select a component. In this case we're expecting that the argument passed to the factory will be the same as the registration name we've used. But we could replace this with other logic. Our factory could even take arguments of other types which we could inspect and determine which string to return.
Configure Your App To Use the Windsor Container
Now, in StartUp, modify ConfigureServices to return IServiceProvider instead of void and create an IServiceProvider that combines services registered directly with the IServiceCollection with those registered with the Windsor container:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var container = new WindsorContainer();
container.Install(new WindsorConfiguration());
return WindsorRegistrationHelper.CreateServiceProvider(container, services);
}
container.Install(new WindsorConfiguration()) allows WindsorConfiguration to configure our container. We could just configure the container right in this method, but this is a nice way to keep our container configurations organized. We can create numerous IWindsorInstaller implementations or our own custom classes to configure the Windsor container.
WindsorRegistrationHelper.CreateServiceProvider(container, services) creates the IServiceProvider that uses container and services.
Does It Work?
I wouldn't post all this without finding out first. Here's some NUnit tests. (I usually write some basic tests for DI configuration.)
The setup creates an IServiceProvider similar to what would happen in the application startup. It creates a container and applies the WindsorConfiguration. I'm also registering a service directly with the ServiceCollection to make sure that the two play well together. Then I'm combining the two into an IServiceProvider.
Then I'm resolving an ICustomerServiceFactory from the IServiceProvider and verifying that it returns the correct implementation of ICustomService for each input string, including the fallback when the string isn't a recognized dependency name.
I'm also verifying that the service registered directly with ServiceCollection is resolved.
public class Tests
{
private IServiceProvider _serviceProvider;
[SetUp]
public void Setup()
{
var services = new ServiceCollection();
services.AddSingleton<IRegisteredWithServiceCollection, RegisteredWithServiceCollection>();
var container = new WindsorContainer();
container.Install(new WindsorConfiguration());
_serviceProvider = WindsorRegistrationHelper.CreateServiceProvider(container, services);
}
[TestCase("TypeOne", typeof(CustomServiceOne))]
[TestCase("TypeTwo", typeof(CustomServiceTwo))]
[TestCase("TYPEThree", typeof(CustomServiceThree))]
[TestCase("unknown", typeof(CustomServiceOne))]
public void FactoryReturnsExpectedService(string input, Type expectedType)
{
var factory = _serviceProvider.GetService<ICustomServiceFactory>();
var service = factory.Create(input);
Assert.IsInstanceOf(expectedType, service);
}
[Test]
public void ServiceProviderReturnsServiceRegisteredWithServiceCollection()
{
var service = _serviceProvider.GetService<IRegisteredWithServiceCollection>();
Assert.IsInstanceOf<RegisteredWithServiceCollection>(service);
}
}
Is All of This Worth It?
Now that I've figured it out, I'd probably use it if I really needed this sort of functionality. It looks worse if you're trying to assimilate both using Windsor with .NET Core and seeing it's abstract factory implementation for the first time. Here's another article with some more information on Windsor's abstract factory without all the noise about .NET Core.
I am going to go out on a limb here and say that the attempt to utilize dependency injection for this purpose is sub-optimal. Normally this would be handled by a Factory pattern that produces service implementations using the dreaded if and switch statements. A simple example is:
public interface IPhotoService {
Photo CreatePhoto(params);
}
public class PhotoServiceFactory {
private readonly IPhotoService _type1;
private readonly IPhotoService _type2;
private readonly IPhotoService _type3;
public PhotoServiceFactory(IDependency1 d1, IDependency2 d2, ...etc) {
_type1 = new ConcreteServiceA(d1);
_type2 = new ConcreteServiceB(d2);
_type3 = new ConcreteServiceC(etc);
}
public IPhotoService Create(User user) {
switch(user.Claim) {
case ClaimEnum.Type1:
return _type1;
case ClaimEnum.Type2:
return _type2;
case ClaimEnum.Type3:
return _type3;
default:
throw new NotImplementedException
}
}
}
Then in your controller:
public class PhotosController {
IPhotoServiceFactory _factory;
public PhotosController(IPhotoServiceFactory factory){
_factory = factory;
}
public IHttpActionResult GetPhoto() {
var photoServiceToUse = _factory.Create(User);
var photo = photoServiceToUse.CreatePhoto(params);
return Ok(photo);
}
}
Alternately just use the concrete classes as arguments in the constructor and follow a similar logic as to the above.
Here is one solution, i have created inside asp.net core console application.
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
namespace CreationalPattern
{
class Program
{
static void Main(string[] args)
{
// Add dependency into service collection
var services = new ServiceCollection()
.AddTransient<FordFigoFactory>()
.AddTransient<AudiQ7Factory>();
/* Create CarServiceFactory as singleton because it can be used across the application more frequently*/
services.AddSingleton<ICarServiceFactory>(provider => new CarServiceFactory(provider));
// create a service provider from the service collection
var serviceProvider = services.BuildServiceProvider();
/* instantiate car*/
var factory = serviceProvider.GetService<ICarServiceFactory>();
var audiCar = factory.Create("audi").CreateACar("Blue");
Console.Read();
}
}
public interface ICarServiceFactory
{
ICreateCars Create(string input);
}
public class CarServiceFactory : ICarServiceFactory
{
private readonly Dictionary<string, ICreateCars> _services
= new Dictionary<string, ICreateCars>(StringComparer.OrdinalIgnoreCase);
public CarServiceFactory(IServiceProvider serviceProvider)
{
_services.Add("ford", serviceProvider.GetService<FordFigoFactory>());
_services.Add("audi", serviceProvider.GetService<AudiQ7Factory>());
}
public ICreateCars Create(string input)
{
Console.WriteLine(input + " car is created.");
return _services.ContainsKey(input) ? _services[input] : _services["ford"];
}
}
public interface ICreateCars
{
Car CreateACar(string color);
}
public class FordFigoFactory : ICreateCars
{
public Car CreateACar(string color)
{
Console.WriteLine("FordFigo car is created with color:" + color);
return new Fordigo { Color = color};
}
}
public class AudiQ7Factory : ICreateCars
{
public Car CreateACar(string color)
{
Console.WriteLine("AudiQ7 car is created with color:" + color);
return new AudiQ7 { Color = color };
}
}
public abstract class Car
{
public string Model { get; set; }
public string Color { get; set; }
public string Company { get; set; }
}
public class Fordigo : Car
{
public Fordigo()
{
Model = "Figo";
Company = "Ford";
}
}
public class AudiQ7 : Car
{
public AudiQ7()
{
Model = "Audi";
Company = "Q7";
}
}
}
Explanation:
To understand better try to read the program from bottom to top. We have 3 sections:
Car (Car, Fordigo, AudiQ7)
CarFactory (ICreateCars, FordFigoFactory, AudiQ7Factory)
CarService (ICarServiceFactory, CarServiceFactory)
In this Dependency injection is registered as transient for Factory classes FordFigoFactory and AudiQ7Factory. And Singleton for CarServiceFactory.

Is it possible to implement dependency injection without using service locator at the start of an application?

I am fairly familiar with concepts of service locator and dependency injection, but there is one thing that gets me confused all the time, i.e., to implement dependency injection for an application we must use some sort of service locator at the start. Please consider the following code,lets say we have some simple DAL class:
public class UserProviderSimple : IUserProvider
{
public void CreateUser(User user)
{
//some code to user here
}
}
And then in the Business Logig Layer we have some simple class that uses IUserProvider that is injected using constructor injection:
public class UserServiceSimple : IUserService
{
public IUserProvider UserProvider { get; set; }
public UserServiceSimple(IUserProvider userProvider)
{
UserProvider = userProvider;
}
public void CreateUser(User user)
{
UserProvider.CreateUser(user);
}
}
Now we may have couple of classes like that and use constructor injection everywhere, but in the main class where the application starts, all these types have to be resolved anyway, hence we must use a service locator to resolve all these types, for example, here I will create a singleton service locator class to resolve all the dependencies at the start of a console application like this:
public class ServiceLocator
{
private readonly UnityContainer _container;
private static ServiceLocator _instance;
public static ServiceLocator Instance()
{
if (_instance == null)
{
_instance = new ServiceLocator();
return _instance;
}
return _instance;
}
private ServiceLocator()
{
_container = new UnityContainer();
_container.RegisterType<IUserProvider, UserProviderSimple>();
_container.RegisterType<IUserService, UserServiceSimple>();
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
}
class Program
{
private static IUserService _userService;
private static void ConfigureDependencies()
{
_userService = ServiceLocator.Instance().Resolve<IUserService();
}
static void Main(string[] args)
{
ConfigureDependencies();
}
}
So it seems like some kind of service locator is always used at the start of the application, hence using service locator is inevitable and it's not correct to always call it an anti-patern right (unless it's used not in the root of the application)?
You misunderstand what a Service Locator is. You do understand the part that it is an anti-pattern, which is good, but what you're missing is that the pattern is not about the mechanics, but the role it plays in the application. In other words:
A DI container encapsulated in a Composition Root is not a Service Locator - it's an infrastructure component.
There is nothing inherently wrong with calling the class encapsulating the DI container bootstrapping code ServiceLocator, but you could also call it a Startup, Bootstrap or ContainerWrapper, it is just a naming convention.
On the other hand ServiceLocator as a design pattern is usually considered an anti-pattern since it becomes a hard dependency for the rest of the code and makes changes and testing hard and unpredictable. In your code it is Resolve<T> method which you would want to stay away from to avoid the consequences.
https://en.m.wikipedia.org/wiki/Service_locator_pattern
And to answer your question, a piece of code is usually required to initialize the DI container in any case even when it is hidden from you as part of a bigger DI framework itself, some frameworks though allow configuring your container from the configuration file too. Hope it helps!
I have struggled with the same question for quite some time. I have make the experience that you usually do not need a ServiceLocator (btw: best description of this anti pattern here and what you can do to avoid it in the corresponding, very awsome, book).
Please see the refactoring of your code below. The basic idea here is that you have just one root object that acts as the composition root (Program) and all child dependencies of the complex object graph below that root are automatically resolved by the container.
public class Bootstrapper
{
private readonly UnityContainer _container;
private Bootstrapper()
{
_container = new UnityContainer();
}
public Program Intialize()
{
this.ConfigureDependencies(UnityContainer container);
return this.GetCompositionRoot();
}
private void ConfigureDependencies()
{
_container.RegisterType<IUserProvider, UserProviderSimple>();
_container.RegisterType<IUserService, UserServiceSimple>();
_container.RegisterType<Program, Program>();
}
private Program GetCompositionRoot()
{
return _container.Resolve<Program>();
}
}
public class Program
{
public Program(IUserService userService)
{
_userService = userService ?? throw AgrumentNullExcpetion(nameof(userService));
}
static void Main(string[] args)
{
var program = new Bootstrapper().Initialize();
program.Run();
}
public void Run()
{
// Do your work using the injected dependency _userService
// and return (exit) when done.
}
}
There are some situations where it does not fit, then YES it's an anti pattern.
We have to look if there are valid usages of the patterns, and for Service Locator there are several use cases.
In a typical line of business application, you should avoid the use of service. It should be the pattern to use when there are no other options.
For instance, inversion of control containers would not work without service location. It's how they resolve the services internally.

Unity dependency not resolving in task

I'm unsure of how to fix my current situation. I'm attempting to create a task:
public class whatever
{
[Dependency]
public IReportingBL ReportingBL { get; set; }
private whatever()
{
...task factory creation, etc.
}
private readonly static Lazy<whatever> _instance = new Lazy<whatever>(() => new whatever());
public static whatever Instance { get { return _instance.Value; }
public Task GetStuff()
{
return _taskFactory.StartNew(() =>
{
return ReportingBL.Method1;
});
}
}
ReportingBL doesn't get resolved. If I create a new instance of ReportingBL inside the thread then the layers below it don't get resolved.
How do I go about getting unity to work in this situation?
You are applying the Singleton Design Pattern. This is a pattern that is frown upon and considered an anti-pattern by some. In Dependency Injection terminology the Singleton pattern can be considered an Ambient Context, which is a pattern that should hardly ever be used in the context of Dependency Injection.
The Singleton Design Pattern does not work well with Dependency Injection, because:
With Dependency Injection it is the application's Composition Root who is in control of creating instances and caching them; not the instance itself.
Having consumers depend on the public Instance field, causes the consumers to violate the Dependency Inversion Principle and disallows the instance from being replaced, mocked, decorated or intercepted. This hinders maintainability and testability of your application.
Further more, in your code I don't see any calls to the Unity DI framework. Please remember that a DI container is not a magical tool that will allow classes to be initialized 'by them selves'. In your code you new up whatever directly; Unity is not involved in this. Unity (or any DI library for that matter) can only auto-wire the object if it is in control of it. In other words, you will have to call container.Resolve<whatever>() for Unity to build up your instance.
Although you could call container.Resoolve from within the Lazy<T> factory delegate, this forces the class to take a dependency on the container itself, which is commonly referred to as the Service Locator anti-pattern.
Instead, I propose the following changes to your design:
Use constructor injection instead of property injection. Property injection leads to Temporal Coupling.
Make the Composition Root and the container responsible for wiring up object graphs.
Stay away from the Singleton design pattern; use the container's Singleton Lifestyle instead.
This results in the following code:
public interface IWhatever
{
Task GetStuff();
}
public class Whatever : IWhatever
{
private readonly IReportingBL reportingBL;
public whatever(IReportingBL reportingBL) {
this.reportingBL = reportingBL;
}
public Task GetStuff() {
return _taskFactory.StartNew(() => {
return ReportingBL.Method1;
});
}
}
// Some consumer of whatever
public class MyController : Controller
{
private readonly IWhatever whatever;
public MyController(IWhatever whatever) {
this.whatever = whatever;
}
public ActionResult Index() {
return View(this.whatever.GetStuff());
}
}
In your composition root, you can configure the class as follows:
var container = new UnityContainer();
container.RegisterType<IReportingBL, ReportingBL>(
new ContainerControlledLifetimeManager());
container.RegisterType<IWhatever, Whatever>(
new ContainerControlledLifetimeManager());
var controller = container.Resolve<MyController>();
controller.Index();

What is Ninject and when do you use it?

I have been helping a few friends on a project and there is a class that uses Ninject. I am fairly new to C# and I have no idea what that class is doing, which is why I need to understand Ninject. Can anyone explain what Ninject is and when does one use it(with example if possible)? Or if you can point to some links that would be great too.
I tried this question: Ninject tutorials/documentations? but it didn't really help a beginner like me.
Ninject is dependency injector for .NET, practical realisation of pattern Dependency Injection (form of Inversion of Control pattern).
Suppose you have two classes DbRepository and Controller:
class Controller {
private DbRepository _repository;
// ... some methods that uses _repository
}
class DbRepository {
// ... some bussiness logic here ...
}
So, now you have two problems:
You must initialize _repository to use it. You have several options for doing this:
Manually, within the constructor. But what if the constructor of DbRepository changes? You would need to rewrite your Controller class because code it's dependent upon was changed. It's not hard if you have only one Controller, but if you have a couple of classes that have a dependency on your Repository you have a real problem.
You can use a service locator or factory. But now you have a dependency on your service locator. You have a global service locator and all code must use it. How you will you change the behavior of your service locator when you need to use it in one part of your code for activation logic but for something else in another part of your code? There is only one way - passing the service locator through constructors. But with more and more classes you will need to pass it more and more times. Anyway, it's a good thought but in the long run, it's a bad idea.
class Controller {
private DbRepository _repository;
public Controller() {
_repository = GlobalServiceLocator.Get<DbRepository>()
}
// ... some methods that uses _repository
}
You can use dependency injection. Look at the code:
class Controller {
private IRepository _repository;
public Controller(IRepository repository) {
_repository = repository;
}
}
Now when you need your controller you write: ninjectDevKernel.Get<Controller>(); or ninjectTestKernel.Get<Controller>();. You can switch beetween dependency resolvers as fast as you want. See? It's simple, you don't need to write a lot.
You can't create unit tests for it. Your Controller has a dependency on DbRepository and if you want to test some method that uses repository, your code will go to the database and ask it for data. That's slow, very slow. If your code in DbRepository changes, your unit test on Controller will fall. Only integration test must warn you of 'problems' in this case. What you need in unit tests - is to isolate your classes and test only one class in one test (in ideal - only one method). If your DbRepository code fails, you will think that Controller code failed - and that's bad (even if you have tests for DbRepository and Controller - they both will fail and you can start from the wrong place). It takes a lot of time to determine where the error really is. You need to know that class A is ok, and it was class B where something failed.
When you want to replace DbRepository with something else in all your classes, you have to do a lot of work.
You can't easily control the lifetime of DbRepository. An object of this class is created on initialization of Controller and deleted when Controller is deleted. There is no sharing between different instances of the Controller class and there is no sharing between other classes. With Ninject you can simply write:
kernel.Bind<IRepository>().To<DbRepository>().InSingletonScope();
A special feature of dependency injection - agile development! You describe that your controller uses a repository with interface IRepository. You don't need to write DbRepository, you can simply create a MemoryRepository class and develop Controller while another person develops DbRepository. When work on DbRepository is finished, you just rebind in your dependency resolver that default IRepository is now DbRepository. Have a lot of controllers? All of them will now use DbRepository. That's cool.
Read more:
Inversion of control (wiki)
Dependency injection (wiki)
Inversion of Control Containers and the Dependency Injection pattern (Martin Fowler)
Ninject is an Inversion of Control container.
What does it do?
Suppose you have a Car class that depends on a Driver class.
public class Car
{
public Car(IDriver driver)
{
///
}
}
In order to use the Car class you build it like so:
IDriver driver = new Driver();
var car = new Car(driver);
A IoC containter centralizes the knowledge about how to build classes. It is a central repository that knows a few things. For example, it knows that the concrete class that you need to use to build a car is a Driver and not any other IDriver.
For example, if you are developing a MVC application, you can tell Ninject how to build your controllers. You do so by registering which concrete classes satisfy specific interfaces. At run time Ninject will figure out which classes are needed to build the required controller, and all behind the scenes.
// Syntax for binding
Bind<IDriver>().To<Driver>();
This is beneficial because it lets you build systems that are more easily unit testable. Suppose that Driver encapsulates all database access for Car. In a unit test for Car you can do this:
IDriver driver = new TestDriver(); // a fake driver that does not go to the db
var car = new Car(driver);
There are entire frameworks that take care of automatically creating testing classes for you and they are called mocking frameworks.
For more information:
GitHub/Ninject Home
Inversion of Control
Inversion of Control Containers and the Dependency Injection pattern
Mock Object
Other answers are great but I would also like to point out this Implementing Dependency Injection using Ninject article.
This is one of the best articles I ever read which explains Dependency Injection and Ninject with a very elegant example.
Here's the snippet from the article:
Below Interface will be implemented by our (SMSService) and (MockSMSService), basically the new Interface (ISMSService) will expose the same behaviors of both services as the code below:
public interface ISMSService
{
void SendSMS(string phoneNumber, string body);
}
(SMSService) implementation to implement the (ISMSService) interface:
public class SMSService : ISMSService
{
public void SendSMS(string mobileNumber, string body)
{
SendSMSUsingGateway(mobileNumber, body);
}
private void SendSMSUsingGateway(string mobileNumber, string body)
{
/*implementation for sending SMS using gateway*/
Console.WriteLine("Sending SMS using gateway to mobile:
{0}. SMS body: {1}", mobileNumber, body);
}
}
(MockSMSService) with totally different implementation using the same interface:
public class MockSMSService :ISMSService
{
public void SendSMS(string phoneNumber, string body)
{
SaveSMSToFile(phoneNumber,body);
}
private void SaveSMSToFile(string mobileNumber, string body)
{
/*implementation for saving SMS to a file*/
Console.WriteLine("Mocking SMS using file to mobile:
{0}. SMS body: {1}", mobileNumber, body);
}
}
we need to implement a change to our (UIHandler) class constructor to pass the dependency through it, by doing this, the code which uses the (UIHandler) can determine which concrete implementation of (ISMSService) to use:
public class UIHandler
{
private readonly ISMSService _SMSService;
public UIHandler(ISMSService SMSService)
{
_SMSService = SMSService;
}
public void SendConfirmationMsg(string mobileNumber) {
_SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
}
}
Now, we have to create a separate class (NinjectBindings) which inherits from (NinjectModule). This class will be responsible to resolve dependencies at run time, then we’ll override the load event which is used to configure the binding in it. The nice thing about Ninject is that we do not need to change our code in (ISMSService), (SMSService), and (MockSMSService).
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ISMSService>().To<MockSMSService>();
}
}
Now in UI form code, we’ll use the binding for Ninject which will determine which implementation to use:
class Program
{
static void Main(string[] args)
{
IKernel _Kernal = new StandardKernel();
_Kernal.Load(Assembly.GetExecutingAssembly());
ISMSService _SMSService = _Kernal.Get<ISMSService>();
UIHandler _UIHandler = new UIHandler(_SMSService);
_UIHandler.SendConfirmationMsg("96279544480");
Console.ReadLine();
}
}
Now the code is using the Ninject Kernal to resolve all chain of dependencies, if we want to use the real service (SMSService) in Release mode (on production environment) instead of the mock one, we need to change on the Ninject binding class (NinjectBindings) only to use the right implementation or by using the #if DEBUG directive as below:
public class NinjectBindings : Ninject.Modules.NinjectModule
{
public override void Load()
{
#if DEBUG
Bind<ISMSService>().To<MockSMSService>();
#else
Bind<ISMSService>().To<SMSService>();
#endif
}
}
Now our binding class (NinjectBindings) is living on the top of all our execution code and we can control the configuration easily in once place.
Also, see What is Inversion of Control? some very simple examples are mentioned to understand IoC.
You have to understand the Dependency Injection(DI) first. Notice here,
public interface IService
{
void Serve();
}
public class Service1 : IService
{
public void Serve() {
Console.WriteLine("Service1 Called");
}
}
public class Service2 : IService
{
public void Serve() {
Console.WriteLine("Service2 Called");
}
}
public class Service3 : IService
{
public void Serve() {
Console.WriteLine("Service3 Called");
}
}
public class Client
{
private IService service;
public Client(IService _service) //Constructor injection
{
service = _service;
}
public void ServeMethod() {
service.Serve(); //Notice here, this Serve() method has no idea what to do.
} // runtime will assign the object, that is Ninject
}
class Program
{
static void Main(string[] args)
{
IService s1 = new Service1(); //N.B. Ninject assigns object with interface
Client c1 = new Client(s1);
c1.ServeMethod();
IService s2 = new Service2(); //N.B. Ninject assigns object with interface
c1 = new Client(s2);
c1.ServeMethod();
IService s3 = new Service3(); //N.B. Ninject assigns object with interface
c1 = new Client(s3);
c1.ServeMethod();
Console.ReadKey();
}
}
// Ninject creates object in runtime for interface in runtime in ASP.NET MVC project.
/*
Output:
Service1 Called
Service2 Called
Service3 Called
*/

C# Dependency Injection and the Strategy Pattern

I'm using Munq as the DI container in a MVC3 project. I have a service layer that retrieves a DTO from a repository. Depending on a property in that DTO I need to use one of two strategies to perform calculations on the DTO. I can register a named type in the container e.g.
Container.Register<ICalculation>("Type1", c => new Type1Calculation);
Container.Register<ICalculation>("Type2", c => new Type2Calculation);
Then I can refer directly to the container when trying to instantiate the appropriate strategy e.g.
var calc = Container.Resolve<ICalculation>(dto.ServiceType);
But this leaves me with a dependency on the container itself with the associated coupling and testing issues. What do I need to pass into the service constructor that would allow me to get the correct calculation but without the dependency on the container? Should I pass in a factory instead so the dependency is in the factory and not in the service class?
Not sure about Munq, but Autofac allows you to pass around Funcs, so that you can skip all factories altogether:
public class Foo
{
public Foo(Func<string, IBar> barFactory) { }
}
Check if Munq allows for such behavior.
Otherwise -- yes, you'll have to resort to hand-written factories to provide yet another level of indirection.
I've added the Munq solution to this. First the factory which includes the IDependencyResolver interface to allow the factory to use the container to resolve dependencies in the factory method:
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
Then in Global.asax.cs register the appropriate interfaces/classes, passing in the container to the factory. So now I can set up my tests and the only extra dependency is IDependencyResolver within the factory:
ioc.Register(c => new CalculationFactory(c));
ioc.Register<ICalculation>("Type1", c => c.Resolve<Type1Calculation>());
ioc.Register<ICalculation>("Type2", c => c.Resolve<Type2Calculation>());
ioc.Register<ICalculation>("InvalidType", c => c.Resolve<InvalidCalculation>());

Categories