Factory method with DI and IoC - c#

I am familiar with these patterns but still don't know how to handle following situation:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}
In general the problem is with amount of references that needs to be injected. It will be even worse when there are more cars.
First approach that comes to my mind is to inject Car1 and Car2 in factory constructor but it is against factory approach because factory will return always the same object. The second approach is to inject servicelocator but it's antipattern everywhere. How to solve it?
Edit:
Alternative way 1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}
Alternative way 2 (too hard to use because of too many of dependencies in tree):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(new Dep1(),new Dep2(new Dep683(),new Dep684()),....)
break;
case B:
return new Car2(new Dep4(),new Dep5(new Dep777(),new Dep684()),....)
break;
}
}
}

Having a switch case statement inside of a factory is a code smell. Interestingly, you don't seem to be focusing on solving that issue at all.
The best, most DI friendly solution for this scenario is the strategy pattern. It allows your DI container to inject the dependencies into the factory instances where they belong, without cluttering up other classes with those dependencies or resorting to a service locator.
Interfaces
public interface ICarFactory
{
ICar CreateCar();
bool AppliesTo(Type type);
}
public interface ICarStrategy
{
ICar CreateCar(Type type);
}
Factories
public class Car1Factory : ICarFactory
{
private readonly IDep1 dep1;
private readonly IDep2 dep2;
private readonly IDep3 dep3;
public Car1Factory(IDep1 dep1, IDep2 dep2, IDep3 dep3)
{
this.dep1 = dep1 ?? throw new ArgumentNullException(nameof(dep1));
this.dep2 = dep2 ?? throw new ArgumentNullException(nameof(dep2));
this.dep3 = dep3 ?? throw new ArgumentNullException(nameof(dep3));
}
public ICar CreateCar()
{
return new Car1(this.dep1, this.dep2, this.dep3);
}
public bool AppliesTo(Type type)
{
return typeof(Car1).Equals(type);
}
}
public class Car2Factory : ICarFactory
{
private readonly IDep4 dep4;
private readonly IDep5 dep5;
private readonly IDep6 dep6;
public Car2Factory(IDep4 dep4, IDep5 dep5, IDep6 dep6)
{
this.dep4 = dep4 ?? throw new ArgumentNullException(nameof(dep4));
this.dep5 = dep5 ?? throw new ArgumentNullException(nameof(dep5));
this.dep6 = dep6 ?? throw new ArgumentNullException(nameof(dep6));
}
public ICar CreateCar()
{
return new Car2(this.dep4, this.dep5, this.dep6);
}
public bool AppliesTo(Type type)
{
return typeof(Car2).Equals(type);
}
}
Strategy
public class CarStrategy : ICarStrategy
{
private readonly ICarFactory[] carFactories;
public CarStrategy(ICarFactory[] carFactories)
{
this.carFactories = carFactories ?? throw new ArgumentNullException(nameof(carFactories));
}
public ICar CreateCar(Type type)
{
var carFactory = this.carFactories
.FirstOrDefault(factory => factory.AppliesTo(type));
if (carFactory == null)
{
throw new InvalidOperationException($"{type} not registered");
}
return carFactory.CreateCar();
}
}
Usage
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6)
});
// And then once it is injected, you would simply do this.
// Note that you could use a magic string or some other
// data type as the parameter if you prefer.
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
Note that because there is no switch case statement, you can add additional factories to the strategy without changing the design, and each of those factories can have their own dependencies that are injected by the DI container.
var strategy = new CarStrategy(new ICarFactory[] {
new Car1Factory(dep1, dep2, dep3),
new Car2Factory(dep4, dep5, dep6),
new Car3Factory(dep7, dep8, dep9)
});
var car1 = strategy.CreateCar(typeof(Car1));
var car2 = strategy.CreateCar(typeof(Car2));
var car3 = strategy.CreateCar(typeof(Car3));

Answering your comment about code example with Composition Root.
You can create following and this is not a Service Locator.
public class CarFactory
{
private readonly Func<Type, ICar> carFactory;
public CarFactory(Func<Type, ICar> carFactory)
{
this.carFactory = carFactory;
}
public ICar CreateCar(Type carType)
{
return carFactory(carType);
}
and this is how look your Composition Root using Unity DI container :
Func<Type, ICar> carFactoryFunc = type => (ICar)container.Resolve(type);
container.RegisterInstance<CarFactory>(new CarFactory(carFactoryFunc));

I answered a similar question some time ago. Basically it's all about your choice. You have to choose between verbosity (which gives you more help from a compiler) and automation, which allows you to write less code but is more prone to bugs.
This is my answer supporting verbosity.
And this is also a good answer that supports automation.
EDIT
I believe the approach you consider wrong is actually the best. Truth being said, usually there won't so many dependencies in there. I like this approach because it's very explicit and rarely results in runtime errors.
Alternative way 1:
This one is bad. It's actually a service locator, which is considered an anti-pattern.
Alternative way 2
Like you wrote, it's not easy to use if mixed with IOC containter. However in some case a similar approach (poor man's DI) can be useful.
All in all, I wouldn't bother having "many" dependencies in your factories. It's a simple, declarative code. It takes seconds to write and can save you hours of struggling with runtime errors.

I would consider giving the dependencies a good structure so you can utilize something similar to Wiktor's answer, but I would abstract the Car factory itself. Then, you don't use the if..then structure.
public interface ICar
{
string Make { get; set; }
string ModelNumber { get; set; }
IBody Body { get; set; }
//IEngine Engine { get; set; }
//More aspects...etc.
}
public interface IBody
{
//IDoor DoorA { get; set; }
//IDoor DoorB { get; set; }
//etc
}
//Group the various specs
public interface IBodySpecs
{
//int NumberOfDoors { get; set; }
//int NumberOfWindows { get; set; }
//string Color { get; set; }
}
public interface ICarSpecs
{
IBodySpecs BodySpecs { get; set; }
//IEngineSpecs EngineSpecs { get; set; }
//etc.
}
public interface ICarFactory<TCar, TCarSpecs>
where TCar : ICar
where TCarSpecs : ICarSpecs
{
//Async cause everything non-trivial should be IMHO!
Task<TCar> CreateCar(TCarSpecs carSpecs);
//Instead of having dependencies ctor-injected or method-injected
//Now, you aren't dealing with complex overloads
IService1 Service1 { get; set; }
IBuilder1 Builder1 { get; set; }
}
public class BaseCar : ICar
{
public string Make { get; set; }
public string ModelNumber { get; set; }
public IBody Body { get; set; }
//public IEngine Engine { get; set; }
}
public class Van : BaseCar
{
public string VanStyle { get; set; }
//etc.
}
public interface IVanSpecs : ICarSpecs
{
string VanStyle { get; set; }
}
public class VanFactory : ICarFactory<Van, IVanSpecs>
{
//Since you are talking of such a huge number of dependencies,
//it may behoove you to properly categorize if they are car or
//car factory dependencies
//These are injected in the factory itself
public IBuilder1 Builder1 { get; set; }
public IService1 Service1 { get; set; }
public async Task<Van> CreateCar(IVanSpecs carSpecs)
{
var van = new Van()
{
//create the actual implementation here.
};
//await something or other
return van;
}
}
I didn't list it, but you can implement multiple types of cars and their corresponding factories now and use DI to inject whatever you need.

First, you have a concrete factory, an IoC container could be an alternative rather than something to help you there.
Then, just refactor the factory to not to expect a full possible parameter list in the factory constructor. This is the primary issue - why are you passing so many parameters if the factory method doesn't need them?
I would rather pass specific parameters to the factory method
public abstract class CarFactoryParams { }
public class Car1FactoryParams : CarFactoryParams
{
public Car1FactoryParams(Dep1, Dep2, Dep3)
{
this.Dep1 = Dep1;
...
}
public class Car2FactoryParams
...
public class CarFactory
{
public ICar CreateCar( CarFactoryParams params )
{
if ( params is Car1FactoryParams )
{
var cp = (Car1FactoryParams)params;
return new Car1( cp.Dep1, cp.Dep2, ... );
}
...
if ( params is ...
By encapsulating the parameter list in a specific class you just make the client provide exactly these parameters that are required for specific factory method invocation.
Edit:
Unfortunately, it was not clear from your post what are these Dep1, ... and how you use them.
I suggest following approach then that separates the factory provider from actual factory implementation. This approach is known as the Local Factory pattern:
public class CarFactory
{
private static Func<type, ICar> _provider;
public static void SetProvider( Func<type, ICar> provider )
{
_provider = provider;
}
public ICar CreateCar(type)
{
return _provider( type );
}
}
The factory itself doesn't have any implementation, it is here to set the foundation to your domain API, where you want your car instances to be created with this API only.
Then, in the Composition Root (somewhere near the starting point of the app where you configure your actual container), you configure the provider:
CarFactory.SetProvider(
type =>
{
switch ( type )
{
case A:
return _container.Resolve<ICar1>();
case B:
return _container.Resolve<ICar2>();
..
}
);
Note that this example implementation of the factory's provider uses a delegate but an interface could also be used as a specification for an actual provider.
This implementation is basically #1 from your edited question, however, it doesn't have any particular downsides. The client still calls:
var car = new CarFactory().CreareCar( type );

Many DI containers support the notion of named dependencies.
E.g. (Structuremap syntax)
For<ICar>().Use<CarA>().Named("aCar");
Container.GetNamedInstance("aCar") // gives you a CarA instance
If you use something like a convention, a rule how the name is derived from the concrete car type itself, you have a situation where you don't need to touch the factory anymore when you extend the system.
Using this in a factory is straightforward.
class Factory(IContainer c) {
public ICar GetCar(string name) {
Return c.GetNamedInstance(name);
}
}

Related

Resolving multiple implementations with generics .net core

I'm trying to figure out how to use multiple implementation of a base class with generics via dependency injection in .net core.
My base class is using generics so I can have different types of List in my response Dto.
I have successfully used many interface and base class implementations when there are no generics involved.
What I've tried so far.
Base class
public abstract class GeneratorBase<T>
{
public abstract ProcessorResponse<T> Process();
}
Response dto
public class ProcessorResponse<T>
{
public ProcessorResponse()
{
Data = new List<T>();
}
public List<T> Data { get; set; }
}
Implementation number 1
public class ConfigurationGenerator : GeneratorBase<ConfigurationModel>
{
public override ProcessorResponse<ConfigurationModel> Process()
{
return new ProcessorResponse<ConfigurationModel>();
}
}
Implementation number 2.
public class ApplicationGenerator : GeneratorBase<ApplicationModel>
{
public override ProcessorResponse<ApplicationModel> Process()
{
return new ProcessorResponse<ApplicationModel>();
}
}
Models
public class ConfigurationModel
{
public int Count { get; set; }
}
public class ApplicationModel
{
public string Title { get; set; }
}
My dependency injection to add the implementations.
public static void AddGenerators(this IServiceCollection services)
{
// add our generators
services.AddScoped<GeneratorBase<ConfigurationModel>, ConfigurationGenerator>();
services.AddScoped<GeneratorBase<ApplicationModel>, ApplicationGenerator>();
}
Main App this is where my error is happening.
public class GeneratorApp
{
// error because T is not implemented
private readonly IEnumerable<GeneratorBase> _generators;
// error because T is not implemented
public GeneratorApp(IEnumerable<GeneratorBase> generators)
{
_generators = generators ?? throw new ArgumentException(nameof(generators));
}
public void RunGenerator(string name)
{
// get the generator by name and run process
var generator = _generators.FirstOrDefault(c => c.GetType().Name == name);
var results = generator.Process();
}
}
Update IFoo Example
IFoo example that works.
public interface IFoo
{
string Name { get; }
}
public class Foo1 : IFoo
{
public string Name => "I'm Foo 1";
}
public class Foo2 : IFoo
{
public string Name => "I'm Foo 2";
}
Dependency injection to add the implementations.
public static void AddGenerators(this IServiceCollection services)
{
// add our Foo's
services.AddTransient<IFoo, Foo1>();
services.AddTransient<IFoo, Foo2>();
}
Main App
public class GeneratorApp
{
private IEnumerable<IFoo> _foos;
public GeneratorApp(IEnumerable<IFoo> foos)
{
_foos = foos;
RunGenerator("Foo1");
}
public void RunGenerator(string name)
{
foreach (var foo in _foos)
{
Console.WriteLine(foo.Name);
}
var foundFoo = _foos.FirstOrDefault(c => c.GetType().Name == name);
if (foundFoo != null)
{
Console.WriteLine(foundFoo.Name);
}
}
}
Console output
I'm Foo 1
I'm Foo 2
I'm Foo 1
The basics
You're misunderstanding the purpose (and correct usage) of dependency injection.
services.AddScoped<IFoo, Foo>();
To put it into words:
If you're creating a object whose constructor needs an IFoo, please insert a Foo instance.
That is the intention of dependency injection: to provide concrete objects even though they (the class' constructors) are asking for vague types.
It allows the classes to be vague, and thus not strongly depend on any particular implementation (= concrete classes).
Your problem
Very simply put, your constructor is asking a parameter type (IEnumerable<GeneratorBase>) that you never registered.
You only registered GeneratorBase<ConfigurationModel> and GeneratorBase<ApplicationModel>, which means that your dependency injection is only able to resolve constructor parameters of those two types. Anything else, the DI framework will throw an exception as it doesn't know how to fill it in.
The solution
It seems like you want a list of all (chosen) types to be injected. Therefore, you must register this exact type. For example:
services.AddScoped<IEnumerable<GeneratorBase>>(() => new List<GeneratorBase>()
{
new ConfigurationGenerator(),
new ApplicationGenerator()
});
This is just the shortest path to workable code. However, there are still further considerations, but your intention and use case simply isn't clear. I strongly suggest reading up on dependency injection as you are missing key knowledge on how to effectively leverage it.
Footnote: You did not post a definition for GeneratorBase (non-generic) but you did reference this type. I'm going to assume that this type exists and you forgot to add it to the question. If not, then there are also some misgivings about polymorphism with generics, which I also suggest you brush up on.

Building complex data class

I have the following builder/factory which abstracts a serializeable model from a class.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
}
}
And I have a concrete implementation of IFooModel like so:
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
}
public class ConcreteFooModel : IFooModel
{
public string AbstractedData1 { get; set; }
public string AbstractedData2 { get; set; }
public int AbstractedData3 { get; set; }
public bool ExtraData1 { get; set; }
}
Now arises the issue, I am struggling to find a way to not reference any concrete implementations in my builder/factory method, e.g.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
}
}
Something about this code is smelly to me, perhaps this is the only way, but I don't like the idea of being forced into referencing the concrete implementation to instantiate the data class, IFooModel.
This gets more complex if I now introduce another data holder interface into the IFooModel
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
IBarData BarData { get; }
}
public interface IBarData
{
// some data in here
}
Forcing me then to create another concrete reference for the nested interface
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
Is there a better way to do this while still sticking to the SOLID principle and IoC?
What's important is to look at this from the perspective of the class that depends on IFooModel That's probably the first place where you want to prevent coupling.
You can accomplish that by injecting the factory into the class that needs it, like this:
public class NeedsFooFactory
{
private readonly IFooBarFactory _factory;
public NeedsFooFactory(IFooBarFactory fooBarFactory)
{
_factory = factory;
}
public void WhatEverThisClassDoes(IFoo foo)
{
var fooBar = _factory.Create(foo);
// Do something
}
}
Now the class that depends on the factory is decoupled from any implementation. You can substitute or mock another implementation of the factory that returns a different implementation of IFooModel.
Something to stop and think about at this point: Do you need an abstraction for ConcreteFooModel at all? If it's just a class that holds data then maybe you don't.
Getting back to the factory: Now that you can replace the factory with any implementation, this becomes less of a concern:
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
This implementation of the factory returns a specific concrete implementation of IFooModel. Is that bad? At some level classes are going to deal with concrete classes. In this case I think it's okay because this factory is doing what it's supposed to do. You don't have to worry that it's coupled to ConcreteFooModel. If you want a class that returns a different implementation you could create a different implementation of IFooBarFactory that returns a different implementation of IFooModel.
Again, this becomes even less of a concern if you question whether you need an abstraction for your foo model. Quite possibly the concrete class is all you need, and what matters is that you can have different implementations of the factory that populates it.

How to resolve constructor injection to pass specific class as a parameter using unity dependency [duplicate]

I'm using Unity and try to follow to SOLID-principles as far as possible. Therefore all implementations only have dependencies to interfaces.
I have a collectionwrapper which looks like this:
public interface ICollectionWrapper<TModel>
{
int TotalCount { get; set; }
IEnumerable<TModel> Items { get; set; }
}
Now I want to create the instance of ICollectionFactory<T> with a factory. This is what I got so far:
public interface ICollectionWrapperFactory
{
ICollectionWrapper<T> CreateCollection<T>();
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items);
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount);
}
public class CollectionWrapperFactory : ICollectionWrapperFactory
{
private readonly IUnityContainer _container;
public CollectionWrapperFactory(IUnityContainer container)
{
_container = container;
}
public ICollectionWrapper<T> CreateCollection<T>()
{
var collectionWrapper = _container.Resolve<ICollectionWrapper<T>>();
return collectionWrapper;
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
{
throw new System.NotImplementedException();
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount)
{
throw new System.NotImplementedException();
}
}
I know that using the container as a servicelocator is considered an anti-pattern, but I don't know any better way to solve this. If there's a better pattern for doing this I'm all ears... An alternative is using the Activator, but then the factory would need to know about the actual implementation of ICollectionWrapper<T>.
But the real problem is that I cannot register the ICollectionWrapper correctly.
container.RegisterType<ICollectionWrapper<T>, CollectionWrapper<T>>(new TransientLifetimeManager()); // Does not compile.
T may be any type. I want to be able to create instances of ICollectionWrapper<T> without having to register every possible combination of T.
Currently I only have one implementation of ICollectionWrapper<T>. But the point is that I really want Unity to be the only part that knows about the actual implementation.
[DataContract]
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
public CollectionWrapper(IEnumerable<TModel> items)
{
Items = items;
}
public CollectionWrapper(IEnumerable<TModel> items, int totalCount)
{
Items = items;
TotalCount = totalCount;
}
public CollectionWrapper()
{
}
[DataMember]
public int TotalCount { get; set; }
[DataMember]
public IEnumerable<TModel> Items { get; set; }
}
T may be any type. I want to be able to create instances of ICollectionWrapper without having to register every possible combination of T.
That's what register generics is for. Some IOC name the method as RegisterGeneric to make it self explanatory (autofac for example), but unity keep it just an overload of RegisterType.
container.RegisterType(typeof(ICollectionWrapper<>), typeof(CollectionWrapper<>), new TransientLifetimeManager());
Also note that your injectable is having multiple constructors. That itself is considered as anti-pattern.
If you fix the multiple construtor thing, above registration will work.
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType(typeof(IEmployee<>), typeof(Employee<>), new TransientLifetimeManager());
}
In case if you're using Configuration File to Register your classes and interfaces, this can be helpful.
<alias alias="TModel" type="{namespace}.TModel, {assemblyname}" />
<register type="{namespace}.ICollectionWrapper[TModel], {assemblyname}"
mapTo="{namespace}.CollectionWrapper, {assemblyname}">
</register>
Here, I'm registering the class(TModel) that I will be using with my Generic Interface(ICollectionWrapper) and Class(CollectionWrapper).
And then I can resolve it through DI
public class MyClass
{
private readonly ICollectionWrapper<TModel> _collectionWrapper;
public MyClass(ICollectionWrapper<TModel> collectionWrapper)
{
_collectionWrapper= collectionWrapper;
}
}

Unity: Register and resolve class with generic type

I'm using Unity and try to follow to SOLID-principles as far as possible. Therefore all implementations only have dependencies to interfaces.
I have a collectionwrapper which looks like this:
public interface ICollectionWrapper<TModel>
{
int TotalCount { get; set; }
IEnumerable<TModel> Items { get; set; }
}
Now I want to create the instance of ICollectionFactory<T> with a factory. This is what I got so far:
public interface ICollectionWrapperFactory
{
ICollectionWrapper<T> CreateCollection<T>();
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items);
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount);
}
public class CollectionWrapperFactory : ICollectionWrapperFactory
{
private readonly IUnityContainer _container;
public CollectionWrapperFactory(IUnityContainer container)
{
_container = container;
}
public ICollectionWrapper<T> CreateCollection<T>()
{
var collectionWrapper = _container.Resolve<ICollectionWrapper<T>>();
return collectionWrapper;
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
{
throw new System.NotImplementedException();
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount)
{
throw new System.NotImplementedException();
}
}
I know that using the container as a servicelocator is considered an anti-pattern, but I don't know any better way to solve this. If there's a better pattern for doing this I'm all ears... An alternative is using the Activator, but then the factory would need to know about the actual implementation of ICollectionWrapper<T>.
But the real problem is that I cannot register the ICollectionWrapper correctly.
container.RegisterType<ICollectionWrapper<T>, CollectionWrapper<T>>(new TransientLifetimeManager()); // Does not compile.
T may be any type. I want to be able to create instances of ICollectionWrapper<T> without having to register every possible combination of T.
Currently I only have one implementation of ICollectionWrapper<T>. But the point is that I really want Unity to be the only part that knows about the actual implementation.
[DataContract]
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
public CollectionWrapper(IEnumerable<TModel> items)
{
Items = items;
}
public CollectionWrapper(IEnumerable<TModel> items, int totalCount)
{
Items = items;
TotalCount = totalCount;
}
public CollectionWrapper()
{
}
[DataMember]
public int TotalCount { get; set; }
[DataMember]
public IEnumerable<TModel> Items { get; set; }
}
T may be any type. I want to be able to create instances of ICollectionWrapper without having to register every possible combination of T.
That's what register generics is for. Some IOC name the method as RegisterGeneric to make it self explanatory (autofac for example), but unity keep it just an overload of RegisterType.
container.RegisterType(typeof(ICollectionWrapper<>), typeof(CollectionWrapper<>), new TransientLifetimeManager());
Also note that your injectable is having multiple constructors. That itself is considered as anti-pattern.
If you fix the multiple construtor thing, above registration will work.
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType(typeof(IEmployee<>), typeof(Employee<>), new TransientLifetimeManager());
}
In case if you're using Configuration File to Register your classes and interfaces, this can be helpful.
<alias alias="TModel" type="{namespace}.TModel, {assemblyname}" />
<register type="{namespace}.ICollectionWrapper[TModel], {assemblyname}"
mapTo="{namespace}.CollectionWrapper, {assemblyname}">
</register>
Here, I'm registering the class(TModel) that I will be using with my Generic Interface(ICollectionWrapper) and Class(CollectionWrapper).
And then I can resolve it through DI
public class MyClass
{
private readonly ICollectionWrapper<TModel> _collectionWrapper;
public MyClass(ICollectionWrapper<TModel> collectionWrapper)
{
_collectionWrapper= collectionWrapper;
}
}

No base class problem, How to use Castle.DynamicProxy Mixin in this particular case?

I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}

Categories

Resources