MvvmCross: IoC with Decorator pattern, two implementations of the same interface - inversion-of-control

I'd like to implement the Decorator pattern in one of my Mvx projects. That is, I'd like to have two implementations of the same interface: one implementation that is available to all of the calling code, and another implementation that is injected into the first implementation.
public interface IExample
{
void DoStuff();
}
public class DecoratorImplementation : IExample
{
private IExample _innerExample;
public Implementation1(IExample innerExample)
{
_innerExample = innerExample;
}
public void DoStuff()
{
// Do other stuff...
_innerExample.DoStuff();
}
}
public class RegularImplementation : IExample
{
public void DoStuff()
{
// Do some stuff...
}
}
Is it possible to wire up the MvvmCross IoC container to register IExample with a DecoratorImplementation containing a RegularImplementation?

It depends.
If DecoratorImplementation is a Singleton, then you could do something like:
Mvx.RegisterSingleton<IExample>(new DecoratorImplementation(new RegularImplementation()));
Then calls to Mvx.Resolve<IExample>() will return the instance of DecoratorImplementation.
However, if you need a new instance, unfortunately the MvvmCross IoC Container doesn't support that. It would be nice if you could do something like:
Mvx.RegisterType<IExample>(() => new DecoratorImplementation(new RegularImplementation()));
Where you'd pass in a lambda expression to create a new instance, similar to StructureMap's ConstructedBy.
Anyway, you may need to create a Factory class to return an instance.
public interface IExampleFactory
{
IExample CreateExample();
}
public class ExampleFactory : IExampleFactory
{
public IExample CreateExample()
{
return new DecoratorImplementation(new RegularImplementation());
}
}
Mvx.RegisterSingleton<IExampleFactory>(new ExampleFactory());
public class SomeClass
{
private IExample _example;
public SomeClass(IExampleFactory factory)
{
_example = factory.CreateExample();
}
}

Related

Autofac: registering hierarchy of classes

I am struggling to register with Autofac a hierarchy of classes and interfaces.
I have an interface IMyService defined as below:
public interface IMyService
{
void DoMyService();
}
And I have two abstract classes with implement this interface and called MyServiceA, and MyServiceB:
public abstract class MyServiceA : IMyService
{
public abstract DoMyService();
}
public abstract class MyServiceB : IMyService
{
public abstract DoMyService();
}
Moreover I have a second-level hierarchy for each of the two aforementioned services: MyServiceA1, MyServiceA2, MyServiceB1 and MyServiceB2:
public class MyServiceA1 : MyServiceA
{
public MyServiceA1() : base() {}
public void DoMyService()
{
// Implementation goes here
}
}
public class MyServiceA2 : MyServiceA
{
public MyServiceA2() : base() {}
public void DoMyService()
{
// Implementation goes here
}
}
public class MyServiceB1 : MyServiceB
{
public MyServiceB1() : base() {}
public void DoMyService()
{
// Implementation goes here
}
}
public class MyServiceB2 : MyServiceB
{
public MyServiceB2() : base() {}
public void DoMyService()
{
// Implementation goes here
}
}
I have in input two enums FirstEnum and SecondEnum used to select which of the four concrete types to instantiate:
public enum FirstEnum
{
SvcA,
SvcB
}
public enum SecondEnum
{
Svc1,
Svc2
}
I want to register IMyService and by providing two enums, It will automatically instantiate the good concrete type.
For instance, if I want to resolve an IMyService and I provide FirstEnum.SvcB and SecondEnum.Svc2, it should instantiate the concrete type MyServiceB2 class. Moreover this hierarchy might be updated by adding some other concrete types etc, so I need a generic way of doing it
Does anyone have a clue to help me?
Thanks
If you want to create a specific service dynamically depending on a set of parameters, this is a good use case for an abstract factory:
public interface IMyServiceFactory
{
IMyService Create(FirstEnum e1, SecondEnum e2);
}
public class MyServiceFactory : IMyServiceFactory
{
private readonly ILifetimeScope scope;
public MyServiceFactory(ILifetimeScope scope)
{
if (scope == null)
throw new ArgumentNullException("scope");
this.scope = scope;
}
public IMyService Create(FirstEnum e1, SecondEnum e2)
{
if (e1 == FirstEnum.SvcA)
{
if (e2 == SecondEnum.Svc1)
{
return scope.Resolve<MyServiceA1>();
}
else //svc2
{
return scope.Resolve<MyServiceA2>();
}
}
else //B
{
if (e2 == SecondEnum.Svc1)
{
return scope.Resolve<MyServiceB1>();
}
else //svc2
{
return scope.Resolve<MyServiceB2>();
}
}
}
}
And now your consumer need to get the factory injected instead of the service:
public class MyServiceConsumer
{
private readonly IMyServiceFactory factory;
public MyServiceConsumer(IMyServiceFactory factory)
{
this.factory = factory;
}
public void Do()
{
//var service = this.factory.Create
}
}
Registration :
Autofac.ContainerBuilder builder = new Autofac.ContainerBuilder();
builder.RegisterType<MyServiceA1>().AsSelf().AsImplementedInterfaces();
builder.RegisterType<MyServiceA2>().AsSelf().AsImplementedInterfaces();
builder.RegisterType<MyServiceB1>().AsSelf().AsImplementedInterfaces();
builder.RegisterType<MyServiceB2>().AsSelf().AsImplementedInterfaces();
builder.RegisterType<MyServiceFactory>().As<IMyServiceFactory>();
builder.RegisterType<MyServiceConsumer>();
//and quick test resolve
var container = builder.Build();
var test = container.Resolve<MyServiceConsumer>();

Autofac - One interface, multiple implementations

Single interface: IDoSomething {...}
Two classes implement that interface:
ClassA : IDoSomething {...}
ClassB : IDoSomething {...}
One class uses any of those classes.
public class DummyClass(IDoSomething doSomething) {...}
code without Autofac:
{
....
IDoSomething myProperty;
if (type == "A")
myProperty = new DummyClass (new ClassA());
else
myProperty = new DummyClass (new ClassB());
myProperty.CallSomeMethod();
....
}
Is it possible to implement something like that using Autofac?
Thanks in advance,
What you are looking for is, as I remember, the Strategy Pattern. You may have N implementations of a single interface. As long you register them all, Autofac or any other DI framework should provide them all.
One of the options would be to create a declaration of the property with private setter or only getter inside Interface then implement that property in each of the class. In the class where you need to select the correct implementation, the constructor should have the parameter IEnumerable<ICommon>.
Autofac or any other DI frameworks should inject all possible implementation. After that, you could spin foreach and search for the desired property.
It may look something like this.
public interface ICommon{
string Identifier{get;}
void commonAction();
}
public class A: ICommon{
public string Identifier { get{return "ClassA";} }
public void commonAction()
{
Console.WriteLine("ClassA");
}
}
public class A: ICommon{
public string Identifier { get{return "ClassB";} }
public void commonAction()
{
Console.WriteLine("ClassA");
}
}
public class Action{
private IEnumerable<ICommon> _common;
public Action(IEnumerable<ICommon> common){
_common = common;
}
public void SelectorMethod(){
foreach(var classes in _common){
if(classes.Identifier == "ClassA"){
classes.commonAction();
}
}
}
}

How do I combine a Controlled Lifetime relationship type (i.e. Owned<T>) with a delegate factory?

In my application, I have a service that requires a constructor parameter not resolved by Autofac, that I instantiate using a delegate factory:
public class Service
{
public Service(string parameter /*, ... other dependencies */)
{
}
public delegate Service Factory(string parameter);
}
This works great! I really love this feature.
I also like the Controlled Lifetime relationship, so I can let my component depend on a Func<Owned<ISomething>> like this:
public class Component
{
private Func<Owned<ISomething>> _somethingFactory;
/* constructor omitted for brevity */
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory())
{
/* Lots of useful code here */
}
}
}
My problem is that now I want to combine the two. I can't have an instance of Func<Owned<Service>> injected, because it needs that parameter, so my current solution is to abstract the factory away into another service, say IServiceFactory:
public interface IServiceFactory
{
Service Create(string parameter);
}
...implemented as such:
public class ServiceFactory : IServiceFactory
{
private Service.Factory _internalFactory;
public ServiceFactory(Service.Factory internalFactory)
{
_internalFactory = internalFactory;
}
public Service Create(string parameter)
{
return _internalFactory(parameter);
}
}
My component then becomes this:
public class Component
{
Func<Owned<IServiceFactory>> _serviceFactoryFactory;
/* ... */
}
The need for such a field name leaves a bad taste in my mouth to the point that I suspect there must be a cleaner way to handle this case.
Is there another way?
You could change your injected factory to include the string parameter:
private Func<string, Owned<ISomething>> _somethingFactory;
Then you can pass the string to the factory when you want to create a new instance:
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory("my parameter"))
{
/* Lots of useful code here */
}
}
I've created a .NET Fiddle with a small working sample.

Injecting a Factory that accepts a Parameter with AutoFac

I've read over several examples that were more complex then I needed and I'm having trouble distilling this down to a simple, concise pattern.
Let's say I have an interface names ICustomService and multiple implementations of ICustomService. I also have a class Consumer that needs to determine at run time which ICustomService to use based upon a parameter.
So I create a classes as follows:
public class Consumer
{
private CustomServiceFactory customServiceFactory;
public Consumer(CustomServiceFactory _customServiceFactory)
{
customServiceFactory = _customServiceFactory;
}
public void Execute(string parameter)
{
ICustomService Service = customServiceFactory.GetService(parameter);
Service.DoSomething();
}
}
public class CustomServiceFactory
{
private IComponentContext context;
public CustomServiceFactory(IComponentContext _context)
{
context = _context;
}
public ICustomService GetService(string p)
{
return context.Resolve<ICustomService>(p); // not correct
}
}
public class ServiceA : ICustomService
{
public void DoSomething()
{
}
}
public class ServiceB : ICustomService
{
public void DoSomething()
{
}
}
Is there an advantage to having my factory implement an interface? How do I fix my factory and register these classes with Autofac so that Consumer.Execute("A") calls DoSomething on WorkerA and Consumer.Execute("B") calls DoSomething on WorkerB?
Thank you
You would register your implementations of ICustomService with keys. For example:
builder.RegisterType<FooService>.Keyed<ICustomService>("someKey");
builder.RegisterType<BarService>.Keyed<ICustomService>("anotherKey");
and then your factory method would be:
public ICustomService GetService(string p)
{
return context.ResolveKeyed<ICustomService>(p);
}
But, you can take this a step further and decouple CustomServiceFactory from IComponentContext:
public class CustomServiceFactory
{
private Func<string, ICustomService> _create;
public CustomServiceFactory(Func<string, ICustomService> create)
{
_create = create;
}
public ICustomService GetService(string p)
{
return _create(p);
}
}
which you would register like so:
builder.Register(c => {
var ctx = c.Resolve<IComponentContext>();
return new CustomServiceFactory(key => ctx.ResolveKeyed<ICustomService>(key));
});
And at that point, assuming CustomServiceFactory doesn't have any other behavior that was omitted for the question, then you as might as well just use and register Func<string, ICustomService> directly.

Parameterless implementation for Ninject mappings

i am creating custom membership provider using ninject for binding to sql classes.
my class in looks like
public MyMembershipProvider(IUsersRepository userRepository)
{
this.userRepository = userRepository;
}
How can i create from this parameterless constructor?
kernel.Bind<IUsersRepository>().To<UsersRepository>();
kernel.Bind<MembershipProvider>().To<MyMembershipProvider>();
and then:
public class AccountController : Controller
{
private readonly MembershipProvider _membershipProvider;
public AccountController(MembershipProvider membershipProvider)
{
_membershipProvider = membershipProvider;
}
public ActionResult Foo()
{
// TODO: Use the membership provider to do some processing
return View();
}
}