Generic decorator with Windsor - c#

I'm trying to figure out how to register the following decorator scenario with Castle Windsor. I have the following interface:
public interface ICalculate<T> where T : class
{
void Calculate(T value);
}
And a couple of implementations where the last one is a decorator.
public class FooCalculator : ICalculate<Foo>
{
public void Calculate(Foo value)
{
// do something here with the value..
}
}
public class BarCalculator : ICalculate<Bar>
{
public void Calculate(Bar value)
{
// do something else here....
}
}
public class CalculatorDecorator<T> : ICalculate<T> where T : class
{
private readonly ICalculate<T> _calculator;
public CalculatorDecorator(ICalculate<T> calculator)
{
_calculator = calculator;
}
public void Calculate(T value)
{
// do for example some logging...
_calculator.Calculate(value);
}
}
This is my registration code
container.Register(Classes.FromAssembly()
.BasedOn(typeof(ICalculate<>))
.WithService.Base());
When i request one of the implementations by their generic interface I want Windsor to resolve the CalculatorDecorator with the requested implementation injected in the constructor.
// I would like calculator to be CalculatorDecorator<Foo> in
// this case but it is FooCalculator.
var calculator = container.Resolve<ICalculate<Foo>>();
// The same goes for this one...
var calculator = containr.Resolve<ICalculate<Bar>>();
Thanks in advance!
Edit:
It works if I do like this
container.Register(Component.For<ICalculate<Foo>>()
.ImplementedBy<CalculatorDecorator<Foo>>(),
Component.For<ICalculate<Foo>>()
.ImplementedBy<FooCalculator>());
container.Register(Component.For<ICalculate<Bar>>()
.ImplementedBy<CalculatorDecorator<Bar>>(),
Component.For<ICalculate<Bar>>()
.ImplementedBy<BarCalculator>());
But I would prefer to register all components if it's possible.

container.Register(AllTypes.FromAssembly()
.BasedOn(typeof(ICalculate<>))
.WithService.Base());
Did you try this? We had a similar situation and this worked for us.
UPDATE
I don't think this is possible because you'll create a circular dependency.
I did get it working like following:
Registration
var container = new WindsorContainer();
container.Register(Component.For(typeof(IDecorator<>)).ImplementedBy(typeof(CalculatorDecorator<>)));
container.Register(AllTypes.FromThisAssembly()
.BasedOn(typeof (ICalculate<>))
.WithService.Base());
var fc = container.Resolve<IDecorator<Foo>>();
var bc = container.Resolve<IDecorator<Bar>>();
Interfaces:
public interface ICalculate<T> where T : class
{
void Calculate(T value);
}
public interface IDecorator<T> : ICalculate<T> where T : class
{
}
Implementation:
public class FooCalculator : ICalculate<Foo>
{
public void Calculate(Foo value)
{
// do something here with the value..
}
}
public class BarCalculator : ICalculate<Bar>
{
public void Calculate(Bar value)
{
// do something else here....
}
}
public class CalculatorDecorator<T>: IDecorator<T> where T : class
{
private readonly ICalculate<T> _calculator;
public CalculatorDecorator(ICalculate<T> calculator)
{
_calculator = calculator;
}
public void Calculate(T value)
{
// do for example some logging...
_calculator.Calculate(value);
}
}

Related

possible to do Func<T1>(T2 param) where T1: Foo<T> and T2 is the T in Foo<T>?

I'm trying to create a screen manager for a game where I should be able to open the screens through said manager using a controller classes
I have this:
public interface IScreenController { }
public class UIScreen<T> where T : IScreenController
{
public void Open(T controller) { }
}
public class ScreenManager
{
public T GetScreen<T>()
{
//some screen getter method here
}
public void Open<T, J>(J controller) where T : UIScreen<J> where J : IScreenController
{
var screen = GetScreen<T>();
screen.Open(controller);
}
}
public class MyScreenController : IScreenController { }
public class OtherScreenController: IScreenController { };
public class MyScreen : UIScreen<MyScreenController> { }
and currently, i can make it work with this:
public class SomeClass
{
public ScreenManager Manager;
public void SomeMethod()
{
Manager.Open<MyScreen, MyScreenController>(new MyScreenController());
}
}
is it possible to do only Manager.Open<MyScreen>(Controller) while keeping enforcing the parameter?
I know i can do Open<T>(IScreenController controller) where T: UIScreen, but that would allow me to put any screen controller as a parameter.
I think you're setting yourself up for a world of heartache here trying to use generics like this. Once you're trying to constrain the types you should begin to ask yourself if it's better to just provide function overloads.
I know you've given us abbreviated code, but instead of:
public interface IScreenController { }
public class UIScreen<T> where T : IScreenController
{
public void Open(T controller) { }
}
Why not just put the Open function in the interface? Then you can ditch UIScreen altogether, or if you really need it to implement some functionality that would make inheritance worthwhile then you could make UIScreen an abstract class, like:
public interface IScreenController
{
public void Open(IScreenController controller) { }
}
public abstract class UIScreen : IScreenController
{
public void Open(IScreenController controller) { // functionality goes here }
}
Another thing you could do is to specify the type as a constructor in your inheritance chain, like instead of what you wrote here:
public class UIScreen<T> where T : IScreenController
{
public void Open(T controller) { }
}
public class MyScreenController : IScreenController { }
public class MyScreen : UIScreen<MyScreenController> { }
You could make UIScreen take an IScreenController as part of the constructor argument, and you could pass that when a subclass is constructed, like the following:
public class UIScreen
{
protected IScreenController screenController;
public UIScreen(IScreenController screenController)
{
this.screenController = screenController;
}
}
public class MyScreenController : IScreenController { }
public class MyScreen : UIScreen
{
public MyScreen() : base(new MyScreenController()) { }
}
then you can do whatever needs doing from your protected IScreenController.
Why
public class UIScreen<T> where T : IScreenController
{
public void Open(T controller) { }
}
and not simply
public class UIScreen
{
public void Open(IScreenController controller) { }
}

dependency injection based on user input

Consider the code snippet (I used the strategy Pattern in the example) :
abstract class SortStrategy
{
public abstract void Sort(ArrayList list);
}
class QuickSort : SortStrategy
{
public override void Sort(ArrayList list)
{
//...
}
}
class ShellSort : SortStrategy
{
public override void Sort(ArrayList list)
{
// ....
}
}
and in Context :
class SortedList
{
private ArrayList list = new ArrayList();
private SortStrategy sortstrategy;
public void SetSortStrategy(SortStrategy sortstrategy)
{
this.sortstrategy = sortstrategy;
}
public void Add(string name)
{
list.Add(name);
}
public void Sort()
{
sortstrategy.Sort(list);
}
}
My question is that the end user through the UI and by selecting an option says to use the method for example QuickSort to sort, but what should I do, how to set SetSortStrategy (or how to dependency injection in this case)
I suggest using factory pattern with dependency injection:
public enum StrategyType
{
A,
B,
C
}
public interface IStrategyFactory {
IStrategy Create();
}
public class BasedOnUserSelStrategyFactory {
public IStrategy Create() {
StrategyType type = ReadUserSelectionFromFile(); // or any place stored
switch (type) {
case StrategyType.A:
return di.Resolve<AStrategy>(); // resolve using di container
case StrategyType.B:
return di.Resolve<BStrategy>(); // resolve using di container
case StrategyType.C:
return di.Resolve<CStrategy>(); // resolve using di container
default:
throw new ArgumentException("type");
}
}
}
Then, register factory in di:
di.Register<IStrategyFactory>().As<BasedOnUserSelStrategyFactory>();
Finally:
IStrategy s = di.Resolve<IStrategyFactory>().Create();
s.MyOperation();
The Castle.Windsor based DI of our MORYX-Framework allows users to configure a ModuleStrategy property in the config.
When a modules config looks like this:
public class ModuleConfig : ConfigBase
{
[DataMember, PluginStrategy(typeof(SortStrategy))]
[ModuleStrategy(typeof(SortStrategy))]
public string SortStrategy { get; set; }
}
The user can choose one of the found classes and every import of SortStragy is automatically filled with an instance. Using the graphic interface the user can select QuickSort and ShellSort, as well as any other implementation found at runtime from a drop-down box.
[Plugin(LifeCycle.Transient, typeof(SortStrategy))]
class QuickSort : SortStrategy
{
// ...
}
class SortedList
{
private ArrayList list = new ArrayList();
// injected with either QuickSort or ShellSort
public SortStrategy Sortstrategy { get; set; }
public void Add(string name)
{
list.Add(name);
}
public void Sort()
{
sortstrategy.Sort(list);
}
}
If you prefer to use the factory pattern, you can also declare a named factory. This can create any strategy registered as shown above.
[PluginFactory(typeof(INameBasedComponentSelector))]
public interface ISortStrategyFactory
{
SortStrategy Create(string name);
void Destroy(SortStrategy instance);
}
If you use Castle.Windsor, this is the code (Licensed under Apache2.0) we use to configure the override on all dependency declarations:
https://github.com/PHOENIXCONTACT/MORYX-Platform/blob/dev/src/Moryx.Container/LocalContainer/LocalRegistrator.cs#L34

How implement Strategy/Facade Pattern using Unity Dependecy Injection Web API

How tell to Unity.WebApi dependency injection framework, inject the correct class in the correct controller?
DI Project Container
public class UnityContainerConfig
{
private static IUnityContainer _unityContainer = null;
public static IUnityContainer Initialize()
{
if (_unityContainer == null)
{
_unityContainer = new Microsoft.Practices.Unity.UnityContainer()
.RegisterType<IMyInterface, MyClass1>("MyClass1")
.RegisterType<IMyInterface, MyClass2>("MyClass2")
}
}
-MVC PROJECT-
public static class UnityConfig
{
public static void RegisterComponents()
{
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(DependencyInjection.UnityContainer.UnityContainerConfig.Initialize());
}
}
Controller 1:
private IMyInterface _myInterface
///MyClass1
public XController(
IMyInterface myInterface
)
{
_myInterface = myInterface
}
Controller 2:
private IMyInterface _myInterface
///MyClass2
public YController(
IMyInterface myInterface
)
{
_myInterface = myInterface
}
Rather than using a strategy or facade to solve this, a better solution would be to redesign your interfaces to be unique per controller. Once you have a unique interface type, your DI container will automatically inject the right service into each controller.
Option 1
Use a generic interface.
public interface IMyInterface<T>
{
}
public class XController
{
private readonly IMyInterface<XClass> myInterface;
public XController(IMyInterface<XClass> myInterface)
{
this.myInterface = myInterface;
}
}
public class YController
{
private readonly IMyInterface<YClass> myInterface;
public YController(IMyInterface<YClass> myInterface)
{
this.myInterface = myInterface;
}
}
Option 2
Use interface inheritance.
public interface IMyInterface
{
}
public interface IXMyInterface : IMyInterface
{
}
public interface IYMyInterface : IMyInterface
{
}
public class XController
{
private readonly IXMyInterface myInterface;
public XController(IXMyInterface myInterface)
{
this.myInterface = myInterface;
}
}
public class YController
{
private readonly IYMyInterface myInterface;
public YController(IYMyInterface myInterface)
{
this.myInterface = myInterface;
}
}

Resolving IEnumerable of generic interfaces from Autofac container

I'm not sure if this is possible, I've seen some other posts asking similar question but none have a satisfactory answer.
What I want to do is resolve a collection of interfaces with differing generic types from Autofac. So constructor of class would look something like this:
public class SomeClass<T> where T : class
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
}
Ideally, I'd just like to be able to register each instance individually like so:
builder
.RegisterType<ImplementationA>()
.As<ITestInterface<A>>();
builder
.RegisterType<ImplementationB>()
.As<ITestInterface<B>>();
I've tried various combinations of RegisterGeneric etc but the Enumerable just keeps coming through empty.
Any help would be appreciated.
I was able to resolve this after playing with inheritance & generic constraints. The solution I ended up with looks like this:
Base classes / interfaces:
public abstract class BaseClass
{
public abstract string IAM { get; }
}
public interface ITestInterface<out T> where T : BaseClass
{
T GetSomething();
}
Implemented classes:
public class A : BaseClass
{
public override string IAM => "I AM TYPE A";
}
public class AInterface : ITestInterface<A>
{
public A GetSomething()
{
return new A();
}
}
public class B : BaseClass
{
public override string IAM => "I AM TYPE B";
}
public class BInterface : ITestInterface<B>
{
public B GetSomething()
{
return new B();
}
}
Class we want to resolve:
public interface ISomeClass
{
void DoSomething();
}
public class SomeClass<T> : ISomeClass where T : BaseClass
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
public void DoSomething()
{
foreach (var t in _testInterfaces)
{
var something = t.GetSomething();
Console.WriteLine(something.IAM);
}
}
}
And finally, Autofac configuration:
var builder = new ContainerBuilder();
builder
.RegisterType<SomeClass<BaseClass>>()
.AsSelf();
builder
.RegisterType<AInterface>()
.As<ITestInterface<BaseClass>>();
builder
.RegisterType<BInterface>()
.As<ITestInterface<BaseClass>>();
builder
.RegisterType<SomeClass<BaseClass>>()
.As<ISomeClass>();
var container = builder.Build();
var x = container.Resolve<ISomeClass>();
x.DoSomething();
Outputs:
I AM TYPE A
I AM TYPE B
Hope this helps someone in the future.
RegisterGeneric should work fine :
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>();
builder.RegisterGeneric(typeof(SomeClass<>))
.As(typeof(ISomeClass<>));
or
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>();
builder.RegisterGeneric(typeof(SomeClass<>))
.AsSelf();
You will find below a working sample :
public interface ISomeClass<T> where T : class
{
Int32 Count { get; }
}
public class SomeClass<T> : ISomeClass<T> where T : class
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
public Int32 Count
{
get
{
return this._testInterfaces.Count();
}
}
}
public interface ITestInterface {}
public interface ITestInterface<T> : ITestInterface { }
public class A { }
public class B { }
public class TestImplementationA : ITestInterface<A> { }
public class TestImplementationB : ITestInterface<B> { }
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>()
.As<ITestInterface>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>()
.As<ITestInterface>();
builder.RegisterGeneric(typeof(SomeClass<>))
.As(typeof(ISomeClass<>));
IContainer container = builder.Build();
var x = container.Resolve<ISomeClass<A>>();
Console.WriteLine(x.Count);
var z = container.Resolve<IEnumerable<ITestInterface>>();
}
}

Constructor Inject with Ninject 2

I've used Ninject with MVC3 for automagic inject of constructor arguments. It worked great.
How do you do something similar with non-MVC code.
For example:
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
public void Strike()
{
_weapon.Strike();
}
}
public class MyProgram
{
public void DoStuff()
{
var Ninja = new Ninja(); // I'm wanting Ninject to call the parameterized Ninja constructor
ninja.Strike();
}
}
How would I alter the code to get it to work?
public interface IWeapon
{
void Strike();
}
public class Sword : IWeapon
{
public void Strike()
{
Console.WriteLine("black ninja strike");
}
}
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
public void Strike()
{
_weapon.Strike();
}
}
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
}
}
class Program
{
static void Main()
{
var kernel = new StandardKernel(new WarriorModule());
var ninja = kernel.Get<Ninja>();
ninja.Strike();
}
}
Wouldn't it just be:
var ninja = Kernel.Get<Ninja>();
You obviously have to resolve the dependency though Ninject.
You need to have an instance of StandardKernel let's call it kernel and then use kernel.Get<Ninja>(). This works since Ninja is non abstract, so it is considered bound to itself. Obviously some concrete types needs to be bound to IWeapon to allow NInject to create Ninja.

Categories