How would I implement the equivalent using Autofac to output 123.
I've had a look at the following but I don't think it quite fits in with what I'm trying to achieve.
http://docs.autofac.org/en/latest/advanced/adapters-decorators.html
Maybe someone can enlighten me - is this decorator?
using System;
namespace Prototypes.Decorator
{
public class Program
{
static void Main()
{
new Class1(new Class2(new Class3(null))).Do();
Console.ReadKey(true);
}
}
public interface ICommand
{
void Do();
}
public abstract class BaseClass : ICommand
{
private readonly ICommand _command;
protected BaseClass(ICommand command)
{
_command = command;
}
public abstract void Do();
public void CallNext()
{
if (_command != null)
{
_command.Do();
}
}
}
public class Class1 : BaseClass
{
public Class1(ICommand command) : base(command)
{
}
public override void Do()
{
Console.Write(1);
CallNext();
}
}
public class Class2 : BaseClass
{
public Class2(ICommand command) : base(command)
{
}
public override void Do()
{
Console.Write(2);
CallNext();
}
}
public class Class3 : BaseClass
{
public Class3(ICommand command) : base(command)
{
}
public override void Do()
{
Console.Write(3);
CallNext();
}
}
}
For bonus points what if there was another interface on the base constructor. Something plausible like protected BaseClass(ICommand command, ILog log) { ... }
There are several ways to build your container in order to achieve what you need, you can use keyed services or lambdas.
Lambdas tend to be a bit less error prone than using strings , so here is a simple container registration that does what you need:
ContainerBuilder cbLambdas = new ContainerBuilder();
cbLambdas.Register<Class3>(ctx => new Class3(null));
cbLambdas.Register<Class2>(ctx => new Class2(ctx.Resolve<Class3>()));
cbLambdas.Register<Class1>(ctx => new Class1(ctx.Resolve<Class2>()));
IContainer containerLambda = cbLambdas.Build();
containerLambda.Resolve<Class1>().Do();
In case of adding ILog interface, as per the following declaration:
public interface ILog
{
void Log();
}
public class NullLog : ILog
{
public void Log() { }
}
And adding it as dependency (in that case only for Class2)
public class Class1 : BaseClass
{
private readonly ILog logger;
public Class1(ICommand command, ILog logger)
: base(command)
{
this.logger = logger;
}
public override void Do()
{
Console.Write(1);
CallNext();
}
}
Then you registration becomes:
ContainerBuilder cbWithLog = new ContainerBuilder();
cbWithLog.RegisterType<NullLog>().As<ILog>();
cbWithLog.Register<Class3>(ctx => new Class3(null));
cbWithLog.Register<Class2>(ctx => new Class2(ctx.Resolve<Class3>()));
cbWithLog.Register<Class1>(ctx => new Class1(ctx.Resolve<Class2>(), ctx.Resolve<ILog>()));
IContainer containerLog = cbWithLog.Build();
containerLog.Resolve<Class1>().Do();
Related
I have a structure like below. I need ideas on how to clearly record all instances. Do you think Microsoft.Extensions.DependencyInjection library is suitable for these?
public interface IRules
{
void Do();
}
Implementation :
public class MyRules:IRules
{
public void Do()
{
//Something;
}
}
Businnes Interface:
public interface IRulesOperation
{
void Do();
}
Businnes class:
public class RulesOperation:IRulesOperation
{
private readonly IRules rules;
private readonly IConfiguration conf;
public RulesOperation(IRules rules,IConfiguration conf)
{
this.conf=conf;
this.rules = rules;
}
public void Do()
{
rules.Do();
}
}
Main Class:
public class App
{
IRulesOperation rules;
public App(IRulesOperation rules)
{
this.rules=rules;
}
}
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;
}
}
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>>();
}
}
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);
}
}
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.