Passing argument in constructor using Simple Injector - c#

I'm having problem in passing parameter dynamically to class constructor using simple injector.
I have following code structure.
Controller example:
public class HomeController : Controller
{
private readonly ICheckService _checkService;
public HomeController(ICheckService checkService)
{
_checkService= checkService;
}
// GET: Home
public ActionResult Index()
{
var list = _checkService.GetAll();
return View(list);
}
}
Service layer (in this layer I need to pass the two constructor parameter for CheckRepository<T> which is implementing ICheckRepository<T>. How do I achieve this using simple injector? I tried but not getting solution around. One example in order to achieve would be really grateful)
public interface ICheckService
{
List<CheckType> GetAll();
}
public class CheckService : ICheckService
{
private readonly ICheckRepository<CheckType> _checkRepository;
public CheckService(ICheckRepository<CheckType> checkRepository)
{
_checkRepository= checkRepository;
}
public List<T> GetAll()
{
return _checkRepository.GetAll().ToList();
}
}
Repository Layer:
public abstract class RepositoryBase<T> where T : class
{
public string Types { get; set; }
public string Segment { get; set; }
public RepositoryBase(string type)
{
Types = type;
}
public RepositoryBase(string type, string segment)
{
Types = type;
Segment = segment;
}
}
public interface ICheckRepository<T> where T : class
{
IEnumerable<T> GetAll();
}
public class CheckRepository<T> : RepositoryBase<T>, ICheckRepository<T> where T : class
{
public CheckRepository(string types, string segment)
: base(types, segment)
{
}
public IEnumerable<T> GetAll()
{
var list = new List<T>();
using (DbAccess dbAccess = new DbAccess(ConnectionString, DatabaseType.SqlServer))
{
return dbAccess.ExecuteReader<T>(StoredProc, CommandType.StoredProcedure).ToList();
}
}
}
My Simple Injector initializer class:
public static void InitializeInjector()
{
var container = new Container();
InitializeContainer(container);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(Container container)
{
container.Register(typeof(IFilterRepository<>), typeof(FilterRepository<>));
//Here is where I am struggling to bind dynamic constructor parameter registering
}
Does anyone have any solution for the above code?
Thanks again.

In case the parameters are fixed to the specific closed-generic types, you should make the registrations as follows:
c.Register<ICheckRepo<Customer>>(() => new CheckRepository<Customer>(constr, "cust_sp"));
c.Register<ICheckRepo<Order>>(() => new CheckRepository<Order>(constr, "order_sp"));
c.Register<ICheckRepo<Product>>(() => new CheckRepository<Product>(constr, "prod_sp"));
// more registrations here
In case your repository mixes dependencies with configuration values, you can also use contextual registration mixed with the registration of the open-generic type:
// Registrations
// One registration for the open generic type
c.Register(typeof(ICheckRepository<>), typeof(CheckRepository<>));
// One registration for the connection string (assuming you only have one)
container.RegisterConditional(typeof(string), CreateStringConstant(constr),
c => c.Consumer.Target.Name == "connectionString");
// Conditional registrations for each closed ICheckRepository<T>
RegisterStoredProcForCheckRepository<Customer>("cuts_sp");
RegisterStoredProcForCheckRepository<Order>("order_sp");
RegisterStoredProcForCheckRepository<Product>("prod_sp");
// more registrations here
// Helper methods
Registration CreateStringConstant(string value) =>
Lifestyle.Singleton.CreateRegistration(typeof(string), () => value, container);
void RegisterStoredProcForCheckRepository<TEntity>(string spName) {
container.RegisterConditional(typeof(string), CreateStringConstant(container, spName),
c => c.Consumer.Target.Name == "segment"
&& c.Contumer.ImplementationType == typeof(CheckRepository<TEntity>));
}
In case the connection string or stored procedure varies per request, you should change the design, as explained here.

Related

workaround a static method in a generic interface

I have a business model TodoItem. I have an API that gives me todoitems. So, I have a corresponding TodoItemModel for each controller (let's name it TodoItemDTO).
The TodoItemDTO class should be able to load itself from a TodoItem business class. So, usually, we would write a static method on the TodoItemDTO class TodoItemDTO FromTodoItem(TodoItem todoItem).
I would like to define an interface for such classes. But unfortunately I can't define a static method in an interface... (note: I use the latest C# version, so, finally, I do, but I should define it... however each class should define its static method)
Here is what I tried:
public interface IDtoModel<TBussinesModel, TDtoModel>
{
TDtoModel FromBusinessModel(TBussinesModel businessObject);
}
public class ToDoItemDTO : IDtoModel<ToDoItem, ToDoItemDTO>
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Description { get; set; }
public bool IsDone { get; private set; }
public ToDoItemDTO FromBusinessModel(ToDoItem businessObject)
{
return new ToDoItemDTO()
{
Id = businessObject.Id,
Title = businessObject.Title,
Description = businessObject.Description,
IsDone = businessObject.IsDone
};
}
}
The only 'problem' here is I have a class method that should be, normally, a static method.
So, by eg, when I define a generic controller, I need to create new objects without any need:
[Route("api/[controller]")]
[ApiController]
public abstract class BaseApiController<TBussinesModel, TDtoModel> : Controller
where TBussinesModel : BaseEntity
where TDtoModel : IDtoModel<TBussinesModel, TDtoModel>, new()
{
protected readonly IRepository _repository;
public BaseApiController(IRepository repository) { _repository = repository; }
[HttpGet("{id:int}")]
public async Task<IActionResult> GetById(int id)
{
var businessObject = await _repository.GetByIdAsync<TBussinesModel>(id);
//
// here bellow, I need to create a new object
//
var dtoObject = (new TDtoModel()).FromBusinessModel(businessObject);
return Ok(dtoObject);
}
[HttpPost]
public abstract Task<IActionResult> Post([FromBody] TDtoModel item);
}
There are lots of options, none of them perfect.
Personally, I would start by turning your factory method into a constructor of the DTO;
public ToDoItemDTO(ToDoItem businessObject)
{
Id = businessObject.Id;
Title = businessObject.Title;
Description = businessObject.Description;
IsDone = businessObject.IsDone;
}
You could define a factory class for each DTO. You could use Activator.CreateInstance to dynamically call the constructor at runtime.
Or you can locate the constructor with reflection, build an Expression tree and compile it.
static Func<TBussinesModel, TDtoModel> GetFactory<TBussinesModel, TDtoModel>()
{
var p = Expression.Parameter(typeof(TBussinesModel), "p");
return Expression.Lambda<Func<TBussinesModel, TDtoModel>>(
Expression.New(
typeof(TDtoModel).GetConstructor(new Type[] { typeof(TBussinesModel) }),
p
),
p)
.Compile();
}

Strategy & factory pattern for base/descendant class resolution

I'm refactoring a codebase and stumbled upon a factory class that created objects based on the subtype passed into the method.
The class basically has one public method with one parameter of which it is a descendant from a base class. Within this method is a switch statement that determines which subtype is passed and conditionally calls different methods to produce the result.
I'm trying to tidy up a bit and figured a strategy pattern might suit the requirements since the code violates the open-closed principle.
Since Autofac is being used, I figured that the transition would be straight forward, however I've hit a bump in the road.
The problem isn't related to Autofac, but rather to the choice of design.
The following code illustrates the class composition, but it is lacking.
public abstract class Parent { }
public class ChildA : Parent { }
public class ChildB : Parent { }
public interface IChildStrategy<T> where T:Parent
{
IEnumerable<object> CreateObjects(Parent child);
}
public class ChildAStrategy : IChildStrategy<ChildA>
{
private IEnumerable<object> CreateObjects(ChildA child)
{
yield return "child A";
}
public IEnumerable<object> CreateObjects(Parent child) =>
CreateObjects(child as ChildA);
}
public class ChildBStrategy : IChildStrategy<ChildB>
{
private IEnumerable<object> CreateObjects(ChildB child)
{
yield return "child b";
yield return "child b's pet";
}
public IEnumerable<object> CreateObjects(Parent child) =>
CreateObjects(child as ChildB);
}
[TestMethod]
public void TestStrategyPattern()
{
var container = builder.Build();
Parent child = new ChildA();
var type = child.GetType();
var strategy = container.Resolve(typeof(IChildStrategy<>)
.MakeGenericType(type));
// strategy.CreateObjects(child);
// Assert.AreEqual("child A", fromDict);
var dict = new Dictionary<Type, Func<Parent, IEnumerable<object>>>();
dict.Add(typeof(ChildA), x => new ChildAStrategy().CreateObjects(x));
dict.Add(typeof(ChildB), x => new ChildBStrategy().CreateObjects(x));
var fromDict = dict[type](child);
Assert.AreEqual("child A", fromDict);
}
I've tried both registering the interface with the generic type itself, like so:
public interface IChildStrategy<T> where T:Parent
{
IEnumerable<object> CreateObjects(T child);
}
But it doesn't really change the difficulties.
Are there any good alternatives to a design pattern for sub-classes?
Updated
Here's what I ended up with. The changes are basically removing the parameter from the CreateObjects method and rather inject it into the constructor as a dependency and registering the strategies as Keyed<T> registrations.
public abstract class Parent { }
public class ChildA : Parent { }
public class ChildB : Parent { }
public interface IChildStrategy
{
IEnumerable<object> CreateObjects();
}
public class ChildAStrategy : IChildStrategy
{
private readonly ChildA childA;
public ChildAStrategy(ChildA childA)
{
this.childA = childA;
}
public IEnumerable<object> CreateObjects()
{
yield return childA;
}
}
public class ChildBStrategy : IChildStrategy
{
private readonly ChildB childB;
public ChildBStrategy(ChildB childB)
{
this.childB = childB;
}
public IEnumerable<object> CreateObjects()
{
yield return childB;
yield return "child b's pet";
}
}
[TestMethod]
public void TestStrategyPattern()
{
var builder = new ContainerBuilder();
builder.RegisterType<ChildAStrategy>().Keyed<IChildStrategy>(typeof(ChildA));
builder.RegisterType<ChildBStrategy>().Keyed<IChildStrategy>(typeof(ChildB));
var container = builder.Build();
IChildStrategy resolve(Parent x) => container.ResolveKeyed<IChildStrategy>(x.GetType(), new TypedParameter(x.GetType(), x));
Parent root;
IChildStrategy strategy;
root = new ChildA();
strategy = resolve(root);
Assert.IsInstanceOfType(strategy, typeof(ChildAStrategy));
Assert.AreSame(root, strategy.CreateObjects().Single());
root = new ChildB();
strategy = resolve(root);
Assert.IsInstanceOfType(strategy, typeof(ChildBStrategy));
Assert.AreSame(root, strategy.CreateObjects().First());
Assert.AreEqual("child b's pet", strategy.CreateObjects().Last());
}
Updated Answer
Original answer is included, below
I think the pattern you're looking for is a Mediator.
Here's an example implementation that fits your needs, as I understand them. This implementation strengthens the typing of the handlers, but makes even heavier use of dynamic in the mediator itself. If performance is a concern, you might want to run some tests--this implementation will probably be slower than your existing code (see: How does having a dynamic variable affect performance?)
using System.Collections.Generic;
using System.Linq;
using Autofac;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace _54542354.MediatorExample
{
/**
* Example Input/Output types
**/
abstract class ActionBase { }
class ExampleAction : ActionBase { public string Name { get; set; } }
class ReturnType { public string Id { get; set; } }
/**
* Interfaces
**/
interface IActionHandler<TAction> where TAction : ActionBase
{
IEnumerable<ReturnType> Handle(TAction action);
}
interface IActionHandlerMediator
{
IEnumerable<ReturnType> Handle(ActionBase action);
}
/**
* Example implementations
**/
class ExampleHandler : IActionHandler<ExampleAction>
{
public IEnumerable<ReturnType> Handle(ExampleAction action)
{
yield return new ReturnType{ Id = $"{action.Name}_First" };
yield return new ReturnType{ Id = $"{action.Name}_Second" };
}
}
class ActionHandlerMediator : IActionHandlerMediator
{
readonly ILifetimeScope container;
public ActionHandlerMediator(ILifetimeScope container)
=> this.container = container;
public IEnumerable<ReturnType> Handle(ActionBase action)
{
// TODO: Error handling. What if no strategy is registered for the provided type?
dynamic handler = container.Resolve(typeof(IActionHandler<>)
.MakeGenericType(action.GetType()));
return (IEnumerable<ReturnType>)handler.Handle((dynamic)action);
}
}
/**
* Usage example
**/
[TestClass]
public class Tests
{
[TestMethod]
public void TestMediator()
{
var builder = new ContainerBuilder();
builder.RegisterType<ExampleHandler>().As<IActionHandler<ExampleAction>>();
builder.RegisterType<ActionHandlerMediator>().As<IActionHandlerMediator>();
var container = builder.Build();
var handler = container.Resolve<IActionHandlerMediator>();
var result = handler.Handle(new ExampleAction() { Name = "MyName" });
Assert.AreEqual("MyName_First", result.First().Id);
Assert.AreEqual("MyName_Second", result.Last().Id);
}
}
}
Original Answer
I took a stab at running your sample code. I had to tweak some things out of the box, but I think it actually worked as you want it to (after my tweaks).
Here's what I ended up with:
[TestMethod]
public void TestStrategyPattern_Dict()
{
// Define the available strategies
var dict = new Dictionary<Type, Func<Parent, IEnumerable<object>>>();
dict.Add(typeof(ChildA), x => new ChildAStrategy().CreateObjects(x));
dict.Add(typeof(ChildB), x => new ChildBStrategy().CreateObjects(x));
// Create the input object
Parent child = new ChildA();
// Invoke the strategy
IEnumerable<object> enumerable = dict[child.GetType()](child);
// Verify the results
Assert.AreEqual("child A", enumerable.Single());
}
[TestMethod]
public void TestStrategyPattern_AutoFac()
{
// Define the available strategies
var builder = new ContainerBuilder();
builder.RegisterType<ChildAStrategy>().As<IChildStrategy<ChildA>>();
builder.RegisterType<ChildBStrategy>().As<IChildStrategy<ChildB>>();
var container = builder.Build();
// Create the input object
Parent child = new ChildA();
// Resolve the strategy
// Because we don't know exactly what type the container will return,
// we need to use `dynamic`
dynamic strategy = container.Resolve(typeof(IChildStrategy<>)
.MakeGenericType(child.GetType()));
// Invoke the strategy
IEnumerable<object> enumerable = strategy.CreateObjects(child);
// Verify the results
Assert.AreEqual("child A", enumerable.Single());
}
These tests both pass. I did not change any code outside of the tests.
The two main changes I introduced are:
Use of .Single() before asserting. This is necessary because the strategy returns an IEnumerable, but the assertion is expecting the first object from that enumerable.
Use of the dynamic type when resolving the strategy from AutoFac. This is necessary because the compiler can't tell what type AutoFac will return. In the original code, the returned type was object, which doesn't have a CreateObjects(Parent) method. dynamic lets us call any method we want--the compiler will just assume it exists. We'll get a runtime exception if the method doesn't exist, but because we know we just created an IChildStrategy<>, we can be confident that the method will exist.

Unity registrations override each other

I'm using Unity in with C#. I have an interface I call IConnectionStringLoader, which have two derived interfaces.
public interface IConnectionStringLoader
{
string Get();
void Write();
}
public interface IDbConnectionStringLoader : IConnectionStringLoader
{
}
public interface IMetaDataConnectionStringLoader : IConnectionStringLoader
{
}
It has only one implementation:
public class ConnectionStringLoader : IDbConnectionStringLoader, IMetaDataConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
My registration looks like this:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("DbConnection"));
The point of the interfaces is that I can inject the different interfaces in my classes and get the correct connectionstring for each implementation. But the problem is that whatever registration is done last will overwrite the previous one.
var foo = _container.Resolve<IDbConnectionStringLoader>();
var bar = _container.Resolve<IMetaDataConnectionStringLoader>();
foo.Write();
bar.Write();
Output is:
DbConnection
DbConnection
If I invert the order of the registration the output will be MetaConnection twice. So my conclusion so far is that the last registration overwrites the previous one. However, if I change the implementation to a derived class it works:
public class SomeOtherConnectionStringLoader : ConnectionStringLoader
{
public ConnectionStringLoaderImpl(string connectionStringName) : base(connectionStringName)
{
}
}
And change the registrations:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, SomeOtherConnectionStringLoader >(new InjectionConstructor("DbConnection"));
Now everything works, but I don't understand why. I've tried different lifetimemanagers, but with the same result. I thought Unity would try to create an instance of ConnectionStringLoader with the "correct" injectionparameter based on the interface, but there's seems to be some other logic at play here.
Any suggestions why the registrations overwrite each other?
Honestly speaking, the way you are using the interfaces looks strange to me because there are two interfaces implemented only by the same class. I would find more natural to follow the next approach using registration names:
// If it is a loader the Write method makes no sense (IConnectionStringRepository?)
public interface IConnectionStringLoader
{
string Get();
void Write();
}
public class ConnectionStringLoader : IConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
Registrations:
container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Database", new InjectionConstructor("MetaConnection"));
container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Metadata", new InjectionConstructor("DbConnection"));
Resolutions:
var foo = _container.Resolve<IConnectionStringLoader>("Database");
var bar = _container.Resolve<IConnectionStringLoader>("Metadata");
foo.Write();
bar.Write();
I'm not familiar with Unity. But it seems they are mapping to same instance. So you should change lifetime of ConnectionStringLoader (Per dependency).
If you will not share instance, why do you put all things in one class ? ConnectionStringLoader Methods = IDbConnectionStringLoader methods + IMetaDataConnectionStringLoader methods.
When you resolve IDbConnectionStringLoader it will not use IMetaDataConnectionStringLoader methods which is already in instance (vice versa it's true).
Crating two different derived class is better at this point:
Abstract class:
public abstract class ConnectionStringLoader : IConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
Derived Classes:
public sealed class DbConnectionStringLoader : ConnectionStringLoader, IDbConnectionStringLoader
{
public DbConnectionStringLoader(string connectionStringName):base(connectionStringName)
{
}
//Implement methods here just belongs to IDbConnectionStringLoader
}
public sealed class MetaDataConnectionStringLoader : ConnectionStringLoader, IMetaDataConnectionStringLoader
{
public MetaDataConnectionStringLoader(string connectionStringName):base(connectionStringName)
{
}
//Implement methods here just belongs to IMetaDataConnectionStringLoader
}
Surprisingly it does call ConnectionStringLoader ctor twice, but with same injection member. If you look at container.Registrations, there are indeed two registrations so it is not override one with other. I did look at implementation of RegisterType, but didn't get my head around it.
One alternative is to name your registrations, not sure if it fits into your overall unity bootstrap strategy.
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>("bar", new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>("foo", new InjectionConstructor("DbConnection"));
var foo = container.Resolve<IDbConnectionStringLoader>("foo");
var bar = container.Resolve<IMetaDataConnectionStringLoader>("bar");

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.

Categories