I have a scenario where there are multiple classes that implement the same interface. the consuming class is to get all the interface implementations as a list so that it can invoke method on all the instances.
public interface IDoSomething
{
void Do();
}
public class Dance : IDoSomething
{
public void Do() { }
}
public class Eat : IDoSomething
{
public void Do() { }
}
public class Person
{
public Person(IEnumerable<IDoSomething> actions)
{
foreach (IDoSomething ds in actions)
{
ds.Do();
}
}
}
How do I register the types so that class Person can resolve all the types that implement IDoSomething. This was possible with Unity, MEF and Spring.NET IOC containers. Trying to do the same with Dry IOC.
You just need to register multiple things as usual with the same interface and whatever implementations. Then inject IEnumerable of your interface, or you may use any other collection interface implemented by .NET array.
Example:
var container = new Container();
container.Register<IDoSomething, Dance>();
container.Register<IDoSomething, Eat>();
container.Register<Person, Person>();
For more information, see the documentation.
Related
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.
public interface IRender
{
void Render();
}
public interface IUpdate
{
void Update(float deltaTime);
}
I have classes that implement IRender, some of these also implement IUpdate.
By using the decorator pattern I am able to extend their Render method.
public abstract class Decorator: IRender
{
protected IRender decoratee;
public Decorator(IRender decoratee)
{
this.decoratee = decoratee;
}
public virtual Render()
{
decoratee.Render();
// add custom rendering code here.
}
}
The beauty of this is that I can created custom rendering behaviour by wrapping an object into multiple decorators like a babushka doll.
My problem is the fact that the IUpdate interface, as well as any other the decoratee implements, will now be hidden by the decorator. I have a number of Systems that accept a list of objects, and operates on them according to the interface they implement. The decorated class will only expose the IRender interface.
What is the cleanest way to get around this issue?
having the class:
public class SomeClass{
public SomeClass(IBlabla bla, string name){
//....
}
}
I can write factory:
public class SomeClassFactory{
public SomeClassFactory(IBlabla bla){
//....
}
public SomeClass Create(string name){return new SomeClass(_bla, name)}
}
And live with it. But I wonder, is there any solution to do this without such obvious factory implementation, in the same way as .AsFactory() works, but with additional parameter?
Definitely possible, and you can even do it without an implementation through the typed factories in Castle. Here is how :
Given your base classes:
public interface IBlabla
{
}
public class Blabla : IBlabla
{
}
public class SomeClass
{
public string Name { get; set; }
public IBlabla Blabla { get; set; }
public SomeClass(IBlabla bla, string named)
{
Blabla = bla;
Name = named;
}
}
you can create a generic factory for elements with a string named in their constructor:
public interface IFactory
{
T Build<T>(string named);
}
No need for any implementation, you are going to use a tool that will create an automatic implementation of your factory backed up by Castle:
// container
var container = new Castle.Windsor.WindsorContainer();
// factory facility, needed to add behavior
container.AddFacility<TypedFactoryFacility>();
// let's register what we need
container.Register(
// your factory interface
Component.For<IFactory>().AsFactory(),
// your IBlabla
Component.For<IBlabla>().ImplementedBy<Blabla>(),
// component, you could register against an interface
Component.For<SomeClass>().ImplementedBy<SomeClass>()
);
// shazam, let's build our SomeClass
var result = container.Resolve<IFactory>().Build<SomeClass>("bla?");
Why does it work? When going through a typed factory, Castle will try and hand the object being resolved all the parameters that are passed to the factory call. So the named parameter is given to the constructor of your SomeClass. The IBlabla is resolved through standard behavior for Castle.
There you are, factory without any implementation are neat :D
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()
}
}
From an instance, I might do this.
var obj= Activator.CreateInstance(GetType());
Not sure how to get typeof of the inherited class in a static base method though.
Is this the best way forward?
public static Method<T>() where T : SomeBase, new()
You could make the base class generic and close the generic in the derived class.
public abstract class CreatorOf<T> where T : CreatorOf<T>
{
public static T Create()
{
return (T)Activator.CreateInstance(typeof(T));
}
}
public class Inheritor : CreatorOf<Inheritor>
{
public Inheritor()
{
}
}
public class Client
{
public Client()
{
var obj = Inheritor.Create();
}
}
There are some who consider this to be an "anti-pattern", but I believe there are circumstances where it is an acceptable approach.
Maybe you should better tryto use abstract factory pattern?
http://en.wikipedia.org/wiki/Abstract_factory_pattern
There is no such thing as a derived static method. So there is no way to create a static factory method that returns a different type depending on which derived class you call it on.
As Lonli-Lokli suggested, you should use the Abstract Factory design pattern.
public interface ISomething
{
void DoSomething();
}
public class SomeClass : ISomething
{
public virtual void DoSomething() { Console.WriteLine("SomeClass"); }
}
public class SomeDerivedClass : SomeClass
{
private int parameter;
public SomeDerivedClass(int parameter)
{
this.parameter = parameter;
}
public virtual void DoSomething()
{
Console.WriteLine("SomeDerivedClass - {0}", parameter);
base.DoSomething();
}
}
public interface IFactory
{
public ISomething Create();
}
public class SomeClassFactory : IFactory
{
public ISomething Create() { return new SomeClass(); }
}
public class SomeDerivedClassFactory : IFactory
{
public ISomething Create() { return new SomeDerivedClass(SomeParam); }
public int SomeParam { get; set; }
}
Pros of Abstract Factory vs static Factory methods:
It is much more flexible, allowing a new implementation of your factory logic (which can be as complicated as you want) for every implementor of the abstract factory. You could have more than one factory per class, if you wanted.
Since you aren't calling a static method, it is much easier to replace at runtime. This is quite useful for injecting mocks in unit tests.
The pros are huge. Abstract Factories are superior to static factory methods in every way, even if you could get static methods to work the way you want them to.
Cons of Abstract Factory vs static Factory methods:
Users of the abstract factory must have a factory instance to create your derived types.
You have to write a new abstract factory implementation for each derived class.
The cons are very marginal.
It is extremely easy for a user to instantiate a factory to create a single object:
MyClass myClass = new MyClassFactory().Create();
As for code duplication in the factory implementation: Saving the implementer a tiny bit of typing is pointless. It is a goal in programming to write code that can be read, understood, and easily modified. There is no programming goal to save paper or keystrokes :)