Is it possible to use contextual bindings with StructureMap - c#

I have an MVC4 controller like:
public MyThingyController
{
IThingy thingy1;
IThingy thingy2;
public MyClass(IThingy thingy1, IThingy thingy2) {
this.thingy1 = thingy1;
this.thingy2 = thingy2;
}
}
IThingy has two different concrete implementations which I'd like to slowly move between
With ninject I'd use a contextual binding
But my google foo is totally failing me in a search to find the equivalent with StructreMap
and So I want to set up StructureMap something like:
public class IocConfig
{
public static IContainer GetCommonServiceLocator()
{
ObjectFactory.Initialize(x =>
{
x.For<IThingy>()
.Use<LegacyThingy>();
x.For<IThingy>()
.Use<ShinyNewThingy>();
});
return ObjectFactory.Container;
}
}

This should do the job:
x.For<MyThingyController>()
// or better interface
// x.For<IMyThingyController>()
.Use<MyThingyController>()
.Ctor<IThingy>("thingy1")
.Is<LegacyThingy>()
.Ctor<IThingy>("thingy2")
.Is<ShinyNewThingy>();

Related

Reduce increasing Constructor service parameters

I'm still new to using Autofac and I'm bothered by the constructor injection method that I'm using. Here's the scenario:
I currently have two classes which inherits the IForms interface. Each of the classes has its own interface as well
public interface IForms
{
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
public interface IFormA : IForms
{ }
public interface IFormB : IForms
{ }
Now I have a class which handles this which is like this:
public class ApplicationForms : IApplicationForms
{
private readonly IFormA _formA;
private readonly IFormB _formB;
public ApplicationForms(IFormA formA, IFormB formB)
{
_formA = formA;
_formB = formB;
}
public void SubmitApplicationForm(FormData data)
{
switch(data.FormType)
{
case FormType.FormA:
_formA.CreateNewForm(data);
break;
case FormType.FormB:
_formB.CreateNewForm(data);
break;
}
}
}
Now there's a possibility that there will be 2 more forms coming in (ex. FormC, FormD, FormE). What will happen here is that there will be 3 more constructor parameters in the ApplicationForms constructor.
Is there a way to like combine all the constructor parameters into one parameter? I can see that it will definitely look ugly in the end.
The problem you're describing is that you have many forms, but at runtime you need one specific form, and so you don't want to inject all of the forms. That might be a good scenario for an abstract factory.
We often represent the factory as an interface with a single method, but we can also do it with a delegate:
public delegate IForm GetFormByTypeFunction(FormType formType);
Now your class looks like this:
public class ApplicationForms : IApplicationForms
{
private readonly GetFormByTypeFunction _getFormByType;
public ApplicationForms(GetFormByTypeFunction getFormByType)
{
_getFormByType = getFormByType;
}
public void SubmitApplicationForm(FormData data)
{
var form = _getFormByType(data.FormType);
form.CreateNewForm(data);
}
}
Now the question is how to implement the factory. It might still have a switch statement or something that doesn't seem too elegant, but that's okay. The point of the factory is that however it works, the business of creating and/or selecting an implementation is moved out of the class that depends on the implementation.
You can register a delegate with Autofac like this:
builder.Register<GetFormByTypeFunction>(context => formType =>
{
switch (formType)
{
case FormType.Type1:
{
return context.Resolve<FormOne>();
}
case FormType.Type2:
{
return context.Resolve<FormTwo>();
}
default:
throw new InvalidOperationException("Unknown form type");
}
});
Now you don't need to resolve all of the IForm implementations up front because you can resolve the one you want directly from the container once you know which one you want.
That might seem "wrong" because you're resolving from the container. But you're not resolving directly from the container. You're depending on a factory. That factory can be replaced with any other implementation which means that your class does not depend on the container.
This sort of factory is also super easy to mock. Technically it's not even a mock. It's just an implementation of the factory that returns a mock.
var formMock = new Mock<IForm>();
var factory = new GetFormByTypeFunction(formType => formMock.Object);
Since there is a common IForms interface, then you can inject an enumeration.
This looks like a good candidate for strategy pattern.
I would suggest refactoring the base interface to be able to identify what type of form it is
public interface IForms {
FormType FormType { get; }
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
and update the dependent class
public class ApplicationForms : IApplicationForms {
private readonly IEnumerable<IForms> forms;
public ApplicationForms(IEnumerable<IForms> forms) {
this.forms = forms;
}
public void SubmitApplicationForm(FormData data) {
var form = forms.FirstOrDefault(_ => _.FormType == data.FormType);
if(form != null)
form.CreateNewForm(data);
//...
}
}
This assumes that when registering the derived interfaces that you associate it with the base IForms interface.
var builder = new ContainerBuilder();
builder.RegisterType<FormA>().As<IForms>();
builder.RegisterType<FormB>().As<IForms>();
builder.RegisterType<FormC>().As<IForms>();
//...
Now no matter how many more forms are added the class can perform without modification.

How to assign a mocked object to a object in controller?

I have a controller which contains a business class that internally has dependencies to a datahandler. For testing that business class I need to mock the datahandler. After setup, I am assigning the business class' datahandler with the mocked datahandler. But while debugging, the business class' datahandler is showing null , I know that I should use the constructor to inject the mocked object.But is it possible to do it without using any constructor injection ?Can any body help me with this?
my business class:
public class FooBusiness
{
public static BarDataHandler _barDatahandler = new BarDataHandler();
...
}
Test class:
public class FooBusinessTest
{
...
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x=>x.Search(It.IsAny<int>).Returns(1);
...
FooBusiness _fooBusiness = new FooBusiness();
FooBusiness._barDatahandler = _mockedBarDataHandler.Object;
//Act
...
}
}
As I mentioned, there are multiple ways to achieve your needs.
Personally I like Shyju's answer more (Constructor Injection), but if you can't change the constructor, you can still change the implementation afterwards by setting the property:
business class:
public class FooBusiness
{
private IBarDataHandler _barDatahandler = new BarDatahandler();
public IBarDataHandler BarDatahandler
{
get { return _barDatahandler; }
set { _barDatahandler = value; }
}
public int Search(int a)
{
return _barDatahandler.Search(a);
}
}
Test class:
public class FooBusinessTest
{
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x => x.Search(It.IsAny<int>).Returns(1);
FooBusiness fooBusiness = new FooBusiness();
fooBusiness.BarDatahandler = _mockedBarDataHandler.Object;
//Act
}
}
If you worry about to refactor the implementation, it is better to setup all the tests first. After that you can refactor with a safer feeling :)
You need to inject your dataHandler dependency to FooBusiness
You need to extract an interface for your BarDataHandler if one does not exist.
interface IBarDataHandler
{
string GetUserToken(int id);
}
public class BarDataHandler : IBarDataHandler
{
public string GetUserToken(int id)
{
// to do :read from db and return
}
}
And add a constructor to FooBusiness class which accepts an implementation of IBarDataHandler.
public class FooBusiness
{
IBarDataHandler barDataHandler;
public FooBusiness(IBarDataHandler barDataHandler)
{
this.barDataHandler=barDataHandler
}
public string GetUserToken(int id)
{
return this.barDataHandler.GetUserToken(id);
}
}
You can use any one of the dependency injection frameworks like Unity/Ninject/StructureMap to resolve your concrete implementation when your app runs.
You can use any mocking framework like Moq to mock the fake implementation of IBarDataHandler in your unittests.

Register generic factory for all types which implements an interface

I have generic factory
public interface IViewModelFactory<T> where T : IViewModel
{
T Create<TU>(TU par);
}
public class ViewModelFactory<T> : IViewModelFactory<T> where T : IViewModel
{
private readonly ILifetimeScope _scope;
public ViewModelFactory(ILifetimeScope scope)
{
_scope = scope;
}
public T Create<TU>(TU par)
{
return _scope.Resolve<T>(new TypedParameter(typeof(TU), par));
}
}
which I can use for resolving viewmodel factory in my window class:
public WRPersons(IViewModelFactory<MRPersons> viewModelFactory)
{
var viewModel = viewModelFactory.Create(new MRPersonsUseCaseParams { Filter = 2 });
...
}
ViewModel is implemented by following code
public class MRPersons : IViewModel
{
public MRPersons(MRPersonsUseCaseParams par)
{
_filter = par.Filter;
}
}
public class MRPersonsUseCaseParams
{
public int Filter { get; set; }
}
Registration in my composition root looks like:
var builder = new ContainerBuilder();
builder.RegisterType<ViewModelFactory<MRPersons>>().As<IViewModelFactory<MRPersons>>();
builder.RegisterType<MRPersons>();
As you can see for each new ViewModel (now its only MRPerson) I will need to create two entries into my composition root. Thus for MRCar it will be:
builder.RegisterType<ViewModelFactory<MRCar>>().As<IViewModelFactory<MRCar>>();
builder.RegisterType<MRCar>();
I would like to automatize these registration somehow. I experimented with RegisterAssemblyTypes/AsClosedTypesOf but without success. Can somebody help me?
EDIT:
Based on answer codeline
builder.RegisterType<ViewModelFactory<MRPersons>>().As<IViewModelFactory<MRPersons>>();
is replaced by
builder.RegisterGeneric(typeof(ViewModelFactory<>)).As(typeof(IViewModelFactory<>));
Full automatic registration looks like:
builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly()).Where(x => iViewModelType.IsAssignableFrom(x) && x.IsClass).AsSelf();
builder.RegisterGeneric(typeof(ViewModelFactory<>)).As(typeof(IViewModelFactory<>));
For better testable solution it would be fine to even replace MRPersons by IMRPersons:
public class MRPersons : IViewModel, IMRPersons
{
public MRPersons(MRPersonsUseCaseParams par)
{
_filter = par.Filter;
}
}
public class MRPersonsUseCaseParams
{
public int Filter { get; set; }
}
public interface IMRPersons
{
}
Thus registration in composition root would looks like (NEED TO BE CORRECTED)
builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly()).Where(x => iViewModelType.IsAssignableFrom(x) && x.IsClass).As<??????>.AsSelf();
This would allows me to pass factory into constructor in following way:
public WRPersons(IViewModelFactory<IMRPersons> viewModelFactory)
{
var viewModel = viewModelFactory.Create(new MRPersonsUseCaseParams { Filter = 2 });
...
}
EDIT2:
During chat with Cyril Durand he provided solution for ViewModelFactory without reference to ILifetimeScope. Here is a code:
public interface IViewModelFactory2<T, TU> where T : IViewModel
{
T Create(TU par);
}
public class ViewModelFactory2<T, TU> : IViewModelFactory2<T, TU> where T : IViewModel
{
private readonly Func<TU, T> _factory;
public ViewModelFactory2(Func<TU, T> factory)
{
_factory = factory;
}
public T Create(TU par)
{
return _factory(par);
}
}
My original factory is Ok too since it is presented in composition root where strong references to DI container can be used.
You want to register ViewModelFactory<> as IViewModelFactory<>, you can do it using the RegisterGeneric method.
builder.RegisterGeneric(typeof(ViewModelFactory<>)).As(typeof(IViewModelFactory<>));
Then you will be able to resolve IViewModelFactory<MRCar> without any other registration.
See Registration Concepts - Open Generic Components for more information
For the second part of the question :
For better testable solution it would be fine to even replace MRPersons by IMRPersons
It is not so easy because there is no way to know which interface to use. You can use the AsImplementedInterfaces which will be equivalent to As<IMRPersons>().As<IViewModel>() but it may be a problem if you have a lot of implemented interface.
builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly())
.Where(x => iViewModelType.IsAssignableFrom(x) && x.IsClass)
.AsImplementedInterfaces();
Or you can use a convention that will register all X asIX but I'm not a big fan of this kind of registration.
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(x => iViewModelType.IsAssignableFrom(x) && x.IsClass)
.As(t => t.GetInterfaces().Where(i => i.Name.EndsWith(t.Name)));
By the way, after chatting, we figured out that you don't need a IViewModelFactory<> at all but you only need a dependency on Func<TParam, T>

How to use "Composite Design Pattern" with Ninject

Validation Rule Contract:
public interface IValidationRule
{
bool IsValid();
}
Concrete Validation Rule:
public class MyClass : IValidationRule
{
public bool IsValid()
{
return true;
}
}
Composite:
public class ValidationRuleComposite : IValidationRule
{
private readonly IEnumerable<IValidationRule> _validationRules;
public ValidationRuleComposite(IEnumerable<IValidationRule> validationRules)
{
_validationRules = validationRules;
}
public bool IsValid()
{
return _validationRules.All(x => x.IsValid());
}
}
When I ask the containter for IValidationRule I want to get ValidationRuleComposite. If I ask the container for a list of IValidationRule I want to get all implementations of IValidationRule except of the ValidationRuleComposite.
How can I achieve this with Ninject?
First you want to set up the bindings for the IEnumerable<IValidationRule> that will be injected into the composite. You can just bind them individually:
// Bind all the individual rules for injection into the composite
kernel.Bind<IValidationRule>().To<MyClass>().WhenInjectedInto<ValidationRuleComposite>();
kernel.Bind<IValidationRule>().To<RuleTwo>().WhenInjectedInto<ValidationRuleComposite>();
Or you can also setup the IEnumerable fairly easy with the convention binding extensions, so that you don't have to add a separate binding for each individual concrete rule. Just be sure to add the Exlcuding clause for the composite class like so:
using Ninject.Extensions.Conventions;
// Bind all the non-composite IValidationRules for injection into ValidationRuleComposite
kernel.Bind(x => x.FromAssemblyContaining(typeof(ValidationRuleComposite))
.SelectAllClasses()
.InheritedFrom<IValidationRule>()
.Excluding<ValidationRuleComposite>()
.BindAllInterfaces()
.Configure(c => c.WhenInjectedInto<ValidationRuleComposite>()));
In my example the composite and the rest of the concretes are in the same assembly, but obviously you can vary your convention binding if they're somewhere else.
Finally, we need to set up the binding so that everywhere else an IValidationRule is request, Ninject provides the composite. There doesn't seem to be an elegant method existing for this, so I wrote my own When clause to avoid the cyclical injection:
// Now bind the composite to the interface for everywhere except itself
kernel.Bind<IValidationRule>().To<ValidationRuleComposite>()
.When(x => x.Target == null
|| x.Target.Member.ReflectedType != typeof(ValidationRuleComposite));
With the help of Soldarnal I came to the following solution:
public static class KernelExtensions
{
public static void BindComposite<TComposite, TCompositeElement>(this StandardKernel container) where TComposite : TCompositeElement
{
container.Bind(x => x.FromAssemblyContaining(typeof(TComposite))
.SelectAllClasses()
.InheritedFrom<TCompositeElement>()
.Excluding<TComposite>()
.BindAllInterfaces()
.Configure(c => c.WhenInjectedInto<TComposite>()));
container.Bind<TCompositeElement>().To<TComposite>()
.When(IsNotCompositeTarget<TComposite>);
}
private static bool IsNotCompositeTarget<TComposite>(IRequest x)
{
if (x.Target == null)
return true;
return x.Target.Member.ReflectedType != typeof(TComposite);
}
}
Usage:
var container = new StandardKernel();
container.BindComposite<ValidationRuleComposite, IValidationRule>();
Here I'm assuming that you want all the validation rules and not a partial list of them, as per the more generic pattern.
I would slightly change the Composition class so that you can do a
kernel.Get<IValidationRuleComposite>()
and a
kernel.GetAll<IValidationRule>()
A simple example follows.
The interfaces
public interface IValidationRule
{
bool IsValid();
}
public interface IValidationRuleComposite : IValidationRule
{
void ValidationRuleCompose(List<IValidationRule> validationRules);
}
and the rules
public class MyClass1 : IValidationRule
{
public bool IsValid()
{
Debug.WriteLine("Valid 1");
return true;
}
}
public class MyClass2 : IValidationRule
{
public bool IsValid()
{
Debug.WriteLine("Valid 2");
return false;
}
}
The composite rule
public class ValidationRuleComposite : IValidationRuleComposite
{
private List<IValidationRule> _validationRules;
public void ValidationRuleCompose(List<IValidationRule> validationRules)
{
_validationRules = _validationRules.Union(validationRules).ToList();
}
public ValidationRuleComposite()
{
_validationRules = new List<IValidationRule>();
}
public bool IsValid()
{
Debug.WriteLine("Composite Valid");
return _validationRules.All(x => x.IsValid());
}
}
and a main
StandardKernel kernel = new StandardKernel();
kernel.Bind<IValidationRule>().To<MyClass1>();
kernel.Bind<IValidationRule>().To<MyClass2>();
kernel.Bind<IValidationRuleComposite>().To<ValidationRuleComposite>();
IValidationRuleComposite try1 = kernel.Get<IValidationRuleComposite>();
IEnumerable<IValidationRule> rules = kernel.GetAll<IValidationRule>();
foreach(IValidationRule trycomp in rules)
{ Debug.WriteLine("trycomp: " + trycomp.GetType().ToString()); trycomp.IsValid(); };
try1.ValidationRuleCompose(rules.ToList());
Console.WriteLine("{0}",try1.IsValid());
Debug.WriteLine("try1: " + try1.GetType().ToString());
EDIT
Equivalent alternative, preserving your composite constructor
public interface IValidationRuleCompositeConstr : IValidationRule
{
}
public class ValidationRuleCompositeOriginal : IValidationRuleCompositeConstr
{
private readonly IEnumerable<IValidationRule> _validationRules;
public ValidationRuleCompositeOriginal(IEnumerable<IValidationRule> validationRules)
{
_validationRules = validationRules;
}
public bool IsValid()
{
return _validationRules.All(x => x.IsValid());
}
}
with corresponding usage:
StandardKernel kernel = new StandardKernel();
kernel.Bind<IValidationRule>().To<MyClass1>();
kernel.Bind<IValidationRule>().To<MyClass2>();
kernel.Bind<IValidationRuleCompositeConstr>().To<ValidationRuleCompositeOriginal>();
IEnumerable<IValidationRule> rules = kernel.GetAll<IValidationRule>();
Ninject.Parameters.ConstructorArgument therules = new Ninject.Parameters.ConstructorArgument("therules", rules);
IValidationRuleCompositeConstr try2 = kernel.Get<IValidationRuleCompositeConstr>(therules);
Debug.WriteLine("Second Class");
Debug.WriteLine (string.Format("{0}",try2.IsValid()));
I don't know how you could do that directly with Ninject, but you could use Ninject to create a class which then creates your validation rules.
public class ValidationRuleFactory : IValidationRuleFactory
{
public IValidationRule CreateComposite()
{
var rules = CreateRules();
return new ValidationRuleComposite(rules);
}
private IEnumerable<IValidationRule> CreateRules()
{
//return all other rules here.
//I would hard code them and add new ones here as they are created.
//If you don't want to do that you could use reflection.
}
}
as this class doesn't hold any state you can then create it with singleton scope.
kernel.Bind<IValidationRuleFactory>().To<ValidationRuleFactory>().InSingletonScope();
Then you inject this class and use it to create your composite
public class MyClass()
{
private readonly IValidationRuleFactory _validationRuleFactory;
public MyClass(IValidationRuleFactory validationRuleFactory)
{
_validationRuleFactory = validationRuleFactory;
}
public bool CheckValid()
{
var composite = _validationRuleFactory.CreateComposite();
return composite.IsValid();
}
}
You wire up your concrete instances of ValidationRule in Ninject, like this.
this.Kernel.Bind<ValidationRule1>().ToSelf();
this.Kernel.Bind<ValidationRule2>().ToSelf();
this.Kernel.Bind<IValidationRule>().To<ValidationRuleComposite>()
.WithConstructorArgument("validationRules",
new IValidationRule[] {
this.Kernel.Get<ValidationRule1>(),
this.Kernel.Get<ValidationRule2>()
});
Now, whenever you have a service that takes an IValidationRule in its constructor, you will get the ValidationRuleComposite concrete type with both ValidationRule1 and ValidationRule2 injected.
As far as I know, Ninject doesn't play nice when it comes to injecting multiple instances of the same type. In this case, we avoid doing that so resolving IValidationRule always results in the composite type.
However, you could build your own scanning convention using Reflection that automatically finds all of the types, excludes any that have the suffix "Composite" in the name, then loops through the types to first bind them to self and then create an array of instances to inject. Have a look at this example of a custom scanning implementation, and its usage.

Implementing the strategy pattern with generics and StructureMap

I am trying to implement the strategy pattern in my repository layer using SM and generics. For that I have an interface, IPocoRepository, which has a concrete implementation using Entity Framework. This I have managed to wire up in my Bootstrapper-file:
For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>));
The problem appears when I try to implement caching for this interface. In my cached class I want an instance of the base repository class, so that I can keep my design DRY. Let me outline how these three files look:
public interface IPocoRepository<T>
{
IQueryable<T> GetAll();
...
public class EntityFrameworkRepository<T> : IPocoRepository<T> where T : class
{
public IQueryable<T> GetAll()
{
...
public class CachedRepository<T> : IPocoRepository<T> where T : class
{
private IPocoRepository<T> _pocoRepository;
public CachedRepository(IPocoRepository<T> pr)
{
_pocoRepository = pr;
}
public IQueryable<T> GetAll()
{
var all = (IQueryable<T>)CacheProvider.Get(_cacheKey);
if (!CacheProvider.IsSet(_cacheKey))
{
all = _pocoRepository.GetAll();
...
Edit: I want StructureMap to return CachedRepository when IPocoRepository is requested, except when requested for in CachedRepository - then I want it to return EntityFrameworkRepository.
I know this is simple when dealing with non-generic classes:
For<ICountyRepository>().Use<CachedCountyRepository>()
.Ctor<ICountyRepository>().Is<CountyRepository>();
I tried searching the documentation for how to do this, but couldn't find anything. Any help would be appreciated!
Ok, this isn't too hard. You can use a type interceptor. Given you have the following classes:
public interface IRepository<T>{}
public class Repository<T>:IRepository<T>{}
public class RepositoryCache<T> : IRepository<T>
{
private readonly IRepository<T> _internalRepo;
public RepositoryCache(IRepository<T> internalRepo)
{
_internalRepo = internalRepo;
}
public IRepository<T> InternalRepo
{
get { return _internalRepo; }
}
}
You will then need to create a type interceptor. You can use the configurable "MatchedTypeInterceptor" provided by StructureMap for this. The interceptor will need to look for your repositories and then figure out what the generic type parameters are. Once it has the type parameters it can declare the type of cache it needs and initialize it. As part of the initialization, it will take the original repository in it's constructor. Then the interceptor will return the completed cache to whatever requested it from the ioc context. Here is the complete sequence inside a test.
This can be moved out into your registry, I just left it all together as an minimal example.
[Test]
public void doTest()
{
MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(
x => x.FindFirstInterfaceThatCloses(typeof (IRepository<>)) != null);
interceptor.InterceptWith(original =>
{
Type closedType = original.GetType()
.FindFirstInterfaceThatCloses(typeof(IRepository<>));
var genericParameters = closedType.GetGenericArguments();
var closedCacheType = typeof(RepositoryCache<>)
.MakeGenericType(genericParameters);
return Activator.CreateInstance(closedCacheType, new[] {original});
});
ObjectFactory.Initialize(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.RegisterInterceptor(interceptor);
});
var test = ObjectFactory.GetInstance<IRepository<int>>();
Assert.That(test is RepositoryCache<int>);
}

Categories