Generic registration in Windsor with UsingFactoryMethod - c#

We currently have code that looks something like below, with a factory being injected in to a lot of classes, which then call the factory to get an instance of what they want.
public class Service
{
public Service(IFactory factory)
{
_car = factory.GetCar<Entity>();
}
}
public class Car : ICar
{
}
public interface IFactory
{
ICar<TEntity> GetCar<TEntity>();
IBoat<TEntity> GetBoat<TEntity>();
}
public class Factory : IFactory
{
ConnectionDetails _connectionDetails;
public Factory(ConnectionDetails connectionDetails)
{
_connectionDetails = connectionDetails;
}
TEntity GetCar<TEntity>()
{
var car = new Car<TEntity>(_connectionDetails);
car.Initialize();
return car;
}
}
I was hoping to be able to create a solution that would allow for request a dependency directly on the Car<TEntity> without needing to go through the factory first.
Below is an example of installing for a single TEntity, but how would I set this up to be generic?
I've tried using open generics, but I can't see how I can get the correct return type out of .UsingFactoryMethod().
I know I can get the RequestedType out of the CreationContext, but I don't see how I can use that to solve this problem.
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICar<TEntity>>().UsingFactoryMethod(
kernel =>
{
var factory = kernel.Resolve<IFactory>();
return factory.GetCar<TEntity>();
}));
}
}

Personally I find that factories mixed with dependency injection can be a bit of anti-pattern, since it hides implementation/creation details somewhere other than the object graph root. In addition, when mixing the two it becomes unclear who ultimately has the responsibility for creating and maintaining objects and their lifecycles.
I'd recommend you move to allowing the container to fully handle creation details based on common base interfaces/classes.
void Main()
{
var container = new WindsorContainer();
container.Install(new Installer());
var car = container.Resolve<Car>();
car.Dump();
}
public class Service
{
private ICar<CarEntity> _car;
public Service(ICar<CarEntity> car)
{
_car = car;
}
}
public class TEntity { }
public class CarEntity : TEntity { }
public class BoatEntity : TEntity { }
public interface ICreatable { }
public interface ICar<TEntity> : ICreatable { }
public class Car : ICar<TEntity>
{
private ConnectionDetails _connectionDetails;
public Car(ConnectionDetails connectionDetails)
{
_connectionDetails = connectionDetails;
Initialize();
}
public void Initialize() {}
}
public class ConnectionDetails { }
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ConnectionDetails>()
.ImplementedBy<ConnectionDetails>());
container.Register(
Classes.FromAssemblyInThisApplication()
.BasedOn(typeof(ICreatable))
.WithServiceAllInterfaces()
.WithServiceSelf()
.LifestyleTransient());
}
}

You can use Castle's Typed Factory Facility to achieve this.
First you need to create an interface that Castle will implement:
public interface IFactory
{
ICar<TEntity> CreateCar<TEntity>(ConnectionDetails connectionDetails);
IBoat<TEntity> CreateBoat<TEntity>(ConnectionDetails connectionDetails);
void Release(object component); // left type as object so it can release either a boat or a car
}
With this implementation as long as your object is registered in the container with the closed generic type as its service name castle will automatically be able to find the correct object.
Then you just need to add the facility and register your factory interface:
kernel.AddFacility<TypedFactoryFacility>();
kernel.Register(Component.For<IFactory>().AsFactory());
The article I linked at the top also covers the naming semantics of the methods in the interface as some words are given special meaning.

Related

Resolve IoC interface to class with same name implicitily

Given a set of interfaces where for each interface there is a corresponding implementing class with the same name (e.g.: ISomeThing : SomeThing), is there a way to automatically resolve all without creating explicit mappings?
There is probably an IoC container that has this already..
This is default convention for StructureMap. It tries to connect concrete classes to interfaces using the I[Something]/[Something] naming convention.
public interface ISpaceship { }
public class Spaceship : ISpaceship { }
public interface IRocket { }
public class Rocket : IRocket { }
[Fact]
public void default_scanning_in_action()
{
var container = new Container(_ =>
{
_.Scan(x =>
{
x.Assembly("<AssemblyNameWhereClassesAreDefined>");
x.WithDefaultConventions();
});
});
var spacesfip = container.GetInstance<ISpaceship>().ShouldBeOfType<Spaceship>();
var rocket = container.GetInstance<IRocket>().ShouldBeOfType<Rocket>();
}

Improve code with Factory Pattern and DI

I am looking on ways to improve the following code:
public interface IExample{ void Do(); }
public interface IExampleA: IExample {}
public class ExampleA: IExampleA { public void Do(); }
public interface IExampleB: IExample {}
public class ExampleB: IExampleB { public void Do(); }
public interface IExampleFactory{
IExample Make(TypesOfExamples thisIsAnEnum);
}
public class ExampleFactory: IExampleFactory {
IExampleA _exampleA;
IExampleB _exampleB;
public ExampleFactory(IExampleA exampleA, IExampleB exampleB)
{
_exampleA = exampleA;
_exampleB = exampleB;
}
public IExample Make(TypesOfExamples thisIsAnEnum)
{
switch(thisIsAnEnum)
{
case A: return _exampleA;
case B: return _exampleB;
}
}
}
Basically what I don't like is having to use the IExampleA and IExampleB, they are there only for being injected:
container.Bind<IExampleA>().To.<ExampleA>();
container.Bind<IExampleB>().To.<ExampleB>();
container.Bind<IExampleFactory>().To.<ExampleFactory>();
And it would be used like this
public class ExampleUsage()
{
ExampleFactory _exampleFactory;
public ExampleUsage(ExampleFactory exampleFactory)
{
_exampleFactory = exampleFactory;
}
public void useFactory(Test obj)
{
var implementation = _exampleFactory.Make(obj.ThisIsAnEnum);
implementation.Do();
}
}
Any pointers would be appreciated, thanks!
**Edit I had forgotten to mention that both ExampleA and ExampleB has some dependencies that need to be taken care of by the DI
public class ExampleA: IExampleA
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
}
public void Do();
}
public class ExampleB: IExampleB
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
IDependencyC _dependencyC;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB, IDependencyC dependencyC)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
_dependencyC = dependencyC;
}
public void Do();
}
container.Bind<IDependencyA>().To.<DependencyA>();
container.Bind<IDependencyB>().To.<DependencyB>();
container.Bind<IDependencyC>().To.<DependencyC>();
I think you are doing wrong with the Factory.
There is no point to inject ExampleA and ExampleB to the Factory.
Since the factory pattern is responsible for creation, therefore you can do instantiation from inside factory class.
This could be easy to replace the factory with the other implementations of the IExampleFactory.
*Edited added more details.
Actually the DI container can be considered as a factory (both are responsible for objects creation).
But if you want to go the factory way, you can implement you own instantiation logic.
Of course, you need to handle the dependencies by the factory.
The factory interface is better to define the objects to be created separately.
public interface IExampleFactory
{
IExampleA CreateExampleA();
IExampleB CreateExampleB();
}
Then the concrete factory should handle the instantiation process of each object.
you can do anything to get all dependencies to instantiate the object (each object can have different dependencies).
public class ExampleFactory: IExampleFactory
{
IExampleA CreateExampleA()
{
//instantiating concrete object A with its dependencies
return concreteA;
}
IExampleB CreateExampleB();
{
//instantiating concrete object B with its dependencies
return concreteB;
}
}

How do would I register this in Castle Windsor?

public interface IDo
{
... details
}
public class DoOneThing : IDo
{
...
}
public class DoAnotherThing : IDo
{
....
}
public interface IFooService
{
... details
}
public class FooService
{
private IDo do;
public FooService(IDo do)
{
// instance is of type specifically resolved per call
this.do = do;
}
...
}
Container.Register(ComponentFor<IDo>().ImplementedBy<DoOneThing>().Named("DoOneThing");
Container.Register(ComponentFor<IFooService>().ImplementedBy<FooService>().DependsOn(Dependency.OnComponent(typeof(IDo), "DoOneThing")).Named("DoItWithOneThing");
Container.Register(ComponentFor<IFooService>().ImplementedBy<FooService>().DependsOn(Dependency.OnComponent(typeof(IDo), "DoAnotherThing")).Named("DoItWithAnotherThing");
Container.Resolve<IFooService>("DoItWithOneThing");
How Do I register FooService to have a dependency of type IDo and then resolve with a specific implementation type? I've tried using something like the code above but I get an exception that no component for service can be found. If I try to resolve to the named instance then it tells me that it's waiting for dependencies of DoOneThing.
You can use the typed Dependency.OnComponent as mentioned in Castle Windsor - multiple implementation of an interface.
See also: Castle Project -- Inline dependencies
var container = new WindsorContainer();
container.Register(
Component
.For<IDo>()
.ImplementedBy<DoAnotherThing>());
container.Register(
Component
.For<IDo>()
.ImplementedBy<DoOneThing>());
container.Register(
Component
.For<IFooService>()
.ImplementedBy<FooService>()
.Named("DoItWithOneThing")
.DependsOn(
Dependency.OnComponent<IDo, DoOneThing>()));
container.Register(
Component
.For<IFooService>()
.ImplementedBy<FooService>()
.Named("DoItWithAnotherThing")
.DependsOn(
Dependency.OnComponent<IDo, DoAnotherThing>()));
Test
var doItWithOneThing = container.Resolve<IFooService>("DoItWithOneThing");
var doItWithAnotherThing = container.Resolve<IFooService>("DoItWithAnotherThing");
Console
.WriteLine(
"doItWithOneThing.Do is DoOneThing // {0}",
doItWithOneThing.Do is DoOneThing);
Console
.WriteLine(
"doItWithAnotherThing.Do is DoAnotherThing // {0}",
doItWithAnotherThing.Do is DoAnotherThing);
Output
doItWithOneThing.Do is DoOneThing // True
doItWithAnotherThing.Do is DoAnotherThing // True
Declarations
public interface IDo {}
public class DoOneThing : IDo {}
public class DoAnotherThing : IDo {}
public interface IFooService
{
IDo Do { get; }
}
public class FooService : IFooService
{
public FooService(IDo #do)
{
Do = #do;
}
public IDo Do { get; private set; }
}

Stack overflow when resolving services with Ninject

I'm trying to resolve a known fixed list of Foo services (in singleton scope) using NInject; this resolution happens in a FooProvider's constructor. The problem is that each Foo will need this provider as well.
public interface IFoo { }
public interface IFooProvider { }
public class Foo : IFoo
{
private readonly IFooProvider _provider;
public Foo(IFooProvider provider)
{
_provider = provider;
}
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
public class Program
{
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
}
There is a logical cyclic loop here, and obviously the stack overflow shows its going down it. However, I have both interface bound to singletons.
Thinking about it; we try to resolve IFoo, which then needs resolution of IFooProvider, itself needing a list of IFoo... but we haven't resolved for any IFoo singletons yet because we're still trying to resolve it!
So how could I work around this?
[Edit] Possible solution; delay buffering of IFoo service instances.
public FooProvider(IKernel kernel)
{
_kernel = kernel;
}
public IFoo Find(object context)
{
if (_allFooServices == null)
_allFooServices = _kernel.GetAll<IFoo>().ToList();
return _allFooServices.Where(...
[Why?]
The general idea is to avoid the service locator pattern, as I've seen it described as an anti-pattern. So, rather than try to resolve services through the dependency injector during run time; you try to get a list of services during setup. The problem with this though, is that if any of your services want to find other services, you have the above problem.
You cannot resolve this cyclic dependency with Ninject. You are not even able to create such object graph by hand.
First you have to remove the cyclic dependency from at least one constructor. You can move this dependency to property and use property injection.
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
If you want to avoid service-locator pattern you should remove dependency on IKernel from the constructor of FooProvider and use the injection of collection of registered IFoo implementations instead.
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IEnumerable<IFoo> fooServices)
{
_allFooServices = fooServices.ToList();
}
}
You could use property injection with one of them.
public interface IFoo
{
}
public interface IFooProvider
{
}
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
Really this seems like bad design, but to answer your question directly, don't instantiate _allFooServices in the constructor. You can do something like this:
private List<IFoo> _allFooServices;
private List<IFoo> AllFooServices
{
get { return _allFooServices ?? (_allFooServices = Kernel.GetAll<IFoo>().ToList()) }
}
Perhaps you can choose a more concrete example, rather than Foo.

Repository pattern with generics and DI

I have a base repository contract which other contracts extend, like follows
public interface IBaseRepository<T> where T : class
{
IList<T> GetContents();
}
and then there are other contracts which extend it like follows
public interface IRepository1 : IBaseRepository<MyClass1>
{
}
public interface IRepository2 : IBaseRepository<MyClass2>
{
}
I implement IRepository1 as follows
public class Repository1 : IRepository1
{
public IList<MyClass1> GetContents()
{
//some code goes here
}
}
similarly for IRepository2
public class Repository2 : IRepository2
{
public IList<MyClass2> GetContents()
{
//some code goes here
}
}
Now i have a service Service1 which implments IService like follows
public class Service1 : IService
{
}
I want to use my base repository (IBaseRepository) here in my service constructor, get an instance of this base repository and use it like so
public class Service1 : IService
{
private IBaseRepository<T> _baseRepository;
public Service1(IBaseRepository<T> baseRepository)
{
_baseRepository = baseRepository;
}
public MyMethod1()
{
var contentsOfType1 = _baseRepository<MyClass1>.GetContents();
}
public MyMethod1()
{
var contentsOfType2 = _baseRepository<MyClass2>.GetContents();
}
}
and this is what i am unable to do.
So i have a generic base repository contract with type T and have other contracts (interfaces) extending the base contract and also specifying what type T will be.
All these contracts (which extend generic base contract) have thier individual implementations.
What i want to do is in my service class, instantiate this generic base contract, and use it to infer the extending types (and hence implementations) and use the method from the base repository.
So if the base contract is
IBaseRepository<T>
and extending contract is
IRepository1 : IBaseRepository<MyClass1>
which is implemented by
Repository1 : IRepository1
i want to use this in my service class like
public class service()
{
*private IBaseRepository<T> _repo;
public service(IBaseRepository<T> repo)
{
*_repo = repo;
}
public void MyMethod()
{
*var x = _repo<MyClass1>.MethodFromIBaseRepository()
}
}
So its the *marked lines i want to achieve, which i am unable to.
I am using castle windsor for DI.
Thanks for your help guys
You should not have other repository interfaces besides your generic IRepository<T>. If you need those, you are missing an abstraction.
For instance, a common reason for people to have custom repository interfaces is because they have a custom query that some repository has, while other don't. For instance:
public interface IEmployeeRepository : IRepository<Employee>
{
Employee GetEmployeeOfTheMonth(int month);
}
The problem here is that the IEmployeeRepository is abused for a 'custom query'. Custom queries deserve their own (generic) abstraction:
// Defines a query
public interface IQuery<TResult>
{
}
// Defines the handler that will execute queries
public interface IQueryHandler<TQuery, TResult>
where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
With this abstraction we can add custom queries to the system, without the need of creating IRepository<T> derivatives:
public class GetEmployeeOfTheMonthQuery : IQuery<Employee>
{
[Range(1, 12)]
public int Month { get; set; }
}
class GetEmployeeOfTheMonthHandler : IQueryHandler<GetEmployeeOfTheMonthQuery, Employee>
{
public Employee Handle(GetEmployeeOfTheMonthQuery query)
{
// todo: query the database, web service, disk, what ever.
}
}
A consumer that needs to know the employee of the month, can now simply take a dependency on IQueryHandler<GetEmployeeOfTheMonthQuery, Employee> and execute the query as follows:
var query = new GetEmployeeOfTheMonthQuery { Month = 11 };
var employee = this.employeeOfMonthHandler.Handle(query);
This might seem like overhead, but this model is very flexible, scalable, and has many interesting benefits. For instance, it is very easy to add cross-cutting concerns by wrapping handlers with decorators.
This also allows our reposities to be hidden behind one generic interface, which allows us to easily batch register them at once and add decorators to them as well.
For more in depth information, read this article: Meanwhile… on the query side of my architecture.
Not possible. The inversion of control container provide dependencies through the constructor, hence it must know in the constructor what type you want to get. So you should do this:
public class service()
{
private IBaseRepository<MyClass1> _repo;
public service(IBaseRepository<MyClass1> repo)
{
_repo = repo;
}
public void MyMethod()
{
var x = _repo.MethodFromIBaseRepository()
}
}

Categories

Resources