Unity with the same interface, multiple factories - c#

So the issue, is when I declare:
[Dependency]
public AuthenticationService _authenticationServices { get; set; }
The _authenticationServices will constantly remain null. It isn't referenced, which will throw a Null Reference Exception. I'm assuming the issue stems from my Unity Configuration file:
container.RegisterType<ICrudFactory, ZNodeDataContextFactory>();
container.RegisterType<ICrudFactory, MincronDataContextFactory>();
Since they both use the same interface, but a separate concrete implementation. The implementation is as follows:
public interface ICrud : IDisposable
{
// Method's to be exposed, via general repository.
}
public interface ICrudFactory
{
ICrud Create();
}
public ZNodeDataContext : DbContext, ICrud
{
// Concrete implementation.
}
public MincronDataContext : DbContext, ICrud
{
// Concrete implementation.
}
public ZNodeDataContextFactory : ICrudFactory
{
ICrud ICrudFactory.Create()
{
return ZNodeDataContext();
}
}
public MincronDataContextFactory : ICrudFactory
{
ICrud ICrudFactory.Create()
{
return MincronDataContext();
}
}
public class AuthenticationService
{
private readonly ICrudFactory _factory;
public AuthenticationService(ICrudFactory factory)
{
_factory = factory;
}
public void Sample()
{
using(var context = _factory.Create())
context.Method(...);
}
}
I'd like to keep that structure, to avoid code duplication.

Do you want to inject ZNodeDataContextFactory into AuthenticationService ? A bit of the point with the injection is that the service should not now anything about the implementation. But if you really want a specific implementation you can create a named instance.
public class AuthenticationService
{
private readonly ICrudFactory _factory;
public AuthenticationService([Dependency("ZNodeData")] ICrudFactory factory)
{
_factory = factory;
}
}
And in your configuration:
container.RegisterType<ICrudFactory, ZNodeDataContextFactory>("ZNodeData");
container.RegisterType<ICrudFactory, MincronDataContextFactory>("MincronData");
Alternatively:
public class AuthenticationService
{
private readonly IEnumerable<ICrudFactory> _factories;
public AuthenticationService(ICrudFactory[] factories)
{
// Now you got both...
_factories = factories;
var zNodeFactory = _factories.FirstOrDefault(x => x.Factory == ZNode);
}
}
public interface ICrudFactory
{
ICrud Create();
// Something to identify the type of data. Maybe an enum?
FactoryType Factory {get;}
}
public ZNodeDataContextFactory : ICrudFactory
{
ICrud ICrudFactory.Create()
{
return ZNodeDataContext();
}
FactoryType ICrudFactory.Factory
{
{get {return FactoryType.ZNode;}
}
}

I ended up solving the issue, by creating particular containers for each generic repository.
public interface IZNodeContextFactory : ICrudFactory
{
}
public interface IMincronContextFactory : ICrudFactory
{
}
By doing it in this manner, I was able to simply do:
container.RegisterType<IZNodeContextFactory, ZNodeContextFactory>();
container.RegisterType<IMincronContextFactory, MincronContextFactory>();
This allowed the automatic dependency resolver to work, and implement since they now had unique names.

Related

Can't add generic Interface to List with same constraint

I'm struggling with generics and don't really know what I'm doing wrong.
This is my example:
public class Repository // Base-class for all repositories
{
public virtual int GetStatus()
{
return 0;
}
}
Repository is just a base class.
public class CarRepository : Repository // base-class for all car repositories
{
private object dataSource;
public override int GetStatus()
{
return dataSource.GetHashCode(); // dummy
}
public virtual int GetPrice(string carName)
{
if (carName.Equals("BMW", StringComparison.OrdinalIgnoreCase)) {
return 100;
}
return 50;
}
}
CarRepository simply provides basic methods to interact with cars.
public class HttpCarRepository : CarRepository // loads the car data from REST Api
{
private dynamic httpClient; // just as an example
public override int GetStatus()
{
return httpClient.IsConnected();
}
public override int GetPrice(string carName)
{
return httpClient.GetAsync("/rest/car/BMW").Result;
}
}
There might also be an DataBaseCarRepository that loads the data from a database. You get the point.
That's for the setup.
Now, I want to cache the results. To keep it generic, I've created this construct:
public interface ICache<TRepo> // Basic Cache Interface
where TRepo : Repository
{
TRepo Repository { get; set; }
}
public class CarCache : CarRepository, ICache<CarRepository>
{
public CarRepository Repository { get; set; }
private dynamic cache;
public CarCache(CarRepository repo)
{
this.Repository = repo;
}
public override int GetPrice(string carName)
{
if (!this.cache.Contains(carName)) {
this.cache.Add(carName, this.Repository.GetPrice(carName));
}
return cache[carName];
}
}
CarCache derives from the base class CarRepository to make it possible to override the methods. It also implements ICache<T> which provides a reference to an actual
implementation of CarRepository, such as HttpCarRepository.
Now I want to add the CarCache to a list of caches.
public class Manager
{
public List<ICache<Repository>> Caches;
}
I've used Repository as the generic type because the ICache<T> interface constraints the type to Repository.
Now the problem:
I've got a method to add a cache that looks like this
static void Add<TCache>(Repository repo)
where TCache : Repository, ICache<TCache>
{
ICache<TCache> newEntry = Activator.CreateInstance(typeof(TCache), repo) as ICache<TCache>;
Caches.Add(newEntry); // Error: Cannot convert from ICache<TCache> to ICache<Repository>
}
That confuses me. From my understanding this should work because I've added the constraint where TCache : Repository to the method, so adding an item of that type
to a list of ICache<Repository> should work. It's the same constraint.
What's the problem here?
One solution would be to make ICache<TRepo> covariant.
You would need to make TRepo Repository get-only to comply with covariant restrictions:
public interface ICache<out TRepo> where TRepo : Repository
{
TRepo Repository { get; }
}
This would work fine as long as the property is only set via your constructor:
public class CarCache : CarRepository, ICache<CarRepository>
{
public CarRepository Repository { get; }
public CarCache(CarRepository repo)
{
this.Repository = repo; // Fine to set Repository here
}
// ...
}
Or you could make the setter private to allow other methods of the implementation class to set the value:
public class CarCache : CarRepository, ICache<CarRepository>
{
public CarRepository Repository { get; private set; }
// ...
void SetRepository(CarRepository repo)
{
this.Repository = repo;
}
}

Implementation of factory method pattern with dependencies

I am trying to better understand the use of the factory method pattern and adhering to SOLID principles and I am not sure if my implementation is correct for the following reasons:
The dependencies my IBankAccountAddOnService implementations need (instantiated in my factory) the larger my BankAccountAddOnFactory constructor is going to get. Shouldn't each IBankAccountAddOnService be responsible for its own dependencies via DI?
In the constructor params for each IBankAccountAddOnService implementation not only do they contain their dependencies but also the concrete type of IBankAccountAddOn specific to that service (e.g. CreditCardAddOn for CreditCardAddOnService). This feels wrong and is why I can't use DI to set them for each service. How could I get the BuildAddOn method to take in the relevant concrete IBankAccountAddOn instead?
Does the switch statement violate the Open Closed Principle or is it ok within a factory? If there were many more bank addons in future, the switch statement may become very large?
IBankAccountAddOn and it's implementations (there may be many of these)
public interface IBankAccountAddOn
{
int Id { get; }
}
public class CreditCardAddOn : IBankAccountAddOn
{
public int Id { get; }
public int CustomerId { get; set; }
public double Limit { get; set; }
public double BalanceTransfer { get; set; }
}
public class TravelInsuranceAddOn : IBankAccountAddOn
{
public int Id { get; }
public int CustomerId { get; set; }
public DateTime Start { get; set; }
public int? MonthsDuration { get; set; }
}
IBankAccountAddOnService that my factory creates dependent upon IBankAccountAddOn
Note - The IExternal... interfaces are from 3rd party libraries.
public interface IBankAccountAddOnResult
{
bool Success { get; set; }
List<string> Errors { get; set; }
}
public class BankAccountAddOnResult : IBankAccountAddOnResult
{
public bool Success { get; set; }
public List<string> Errors { get; set; }
}
public interface IBankAccountAddOnService
{
IBankAccountAddOnResult BuildAddOn();
}
public class CreditCardAddOnService : IBankAccountAddOnService
{
private readonly IExternalCreditCardService _creditCardService;
private readonly IRepository _repository;
private readonly CreditCardAddOn _creditCardAddOn;
public CreditCardAddOnService(IExternalCreditCardService creditCardService, IRepository repository, CreditCardAddOn creditCardAddOn)
{
_creditCardService = creditCardService;
_repository = repository;
_creditCardAddOn = creditCardAddOn;
}
public IBankAccountAddOnResult BuildAddOn()
{
var customerDetails = _repository.GetCustomer(_creditCardAddOn.CustomerId);
if (!customerDetails.CanApplyCreditCards)
{
return new BankAccountAddOnResult
{
Success = false,
Errors = new List<string>{
"Customer cannot apply for credit cards"
}
};
}
var result = _creditCardService.Apply(_creditCardAddOn);
return result;
}
}
public class TravelInsuranceAddOnService : IBankAccountAddOnService
{
private readonly IExternalTravelInsuranceService _travelInsuranceService;
private readonly TravelInsuranceAddOn _travelInsuranceAddOn;
public TravelInsuranceAddOnService(IExternalTravelInsuranceService travelInsuranceService, TravelInsuranceAddOn travelInsurance)
{
_travelInsuranceService = travelInsuranceService;
_travelInsuranceAddOn = travelInsurance;
}
public IBankAccountAddOnResult BuildAddOn()
{
var result = _travelInsuranceService.Apply(_travelInsuranceAddOn.CustomerId, _travelInsuranceAddOn.MonthsDuration, _travelInsuranceAddOn.Start);
return result;
}
}
Factory implementation
public interface IBankAccountAddOnFactory
{
IBankAccountAddOnService Create(IBankAccountAddOn addOn);
}
public class BankAccountAddOnFactory : IBankAccountAddOnFactory
{
private readonly IExternalCreditCardService _creditCardService;
private readonly IExternalTravelInsuranceService _travelInsuranceService;
private readonly IRepository _repository;
public BankAccountAddOnFactory(
IExternalCreditCardService creditCardService,
IExternalTravelInsuranceService travelInsuranceService,
IRepository repository
)
{
_creditCardService = creditCardService;
_travelInsuranceService = travelInsuranceService;
_repository = repository;
}
public IBankAccountAddOnService Create(IBankAccountAddOn addOn)
{
switch (addOn)
{
case CreditCardAddOn creditCard:
return new CreditCardAddOnService(_creditCardService, _repository, creditCard);
case TravelInsuranceAddOn travelInsurance:
return new TravelInsuranceAddOnService(_travelInsuranceService, travelInsurance);
//Many other addon cases
default:
throw new ArgumentOutOfRangeException();
}
}
}
Service that creates add ons for customers
public class BankAccountAddOnService
{
private IBankAccountAddOnFactory _bankAddOnFactory;
public BankAccountAddOnService(IBankAccountAddOnFactory bankAddOnFactory)
{
_bankAddOnFactory = bankAddOnFactory;
}
public IBankAccountAddOnResult Apply(IBankAccountAddOn addOn)
{
var applyService = _bankAddOnFactory.Create(addOn);
var response = applyService.BuildAddOn();
//Do something with response
return response;
}
}
The dependencies my IBankAccountAddOnService implementations need (instantiated in my factory) the larger my BankAccountAddOnFactory constructor is going to get. Shouldn't each IBankAccountAddOnService be responsible for its own dependencies via DI?
I don't understand "each [service] be responsible for its own dependencies via DI." The whole point of DI is that classes are not responsible for their own dependencies-- the code that instantiates the class is.
And yes it is normal to have a constructor with more and more arguments as dependencies are added. If you have trouble with this, see Constructor injection: How many dependencies is too many?.
In the constructor params for each IBankAccountAddOnService implementation not only do they contain their dependencies but also the concrete type of IBankAccountAddOn specific to that service (e.g. CreditCardAddOn for CreditCardAddOnService). This feels wrong and is why I can't use DI to set them for each service. How could I get the BuildAddOn method to take in the relevant concrete IBankAccountAddOn instead?
It's okay to inject a concrete type, obviously, but the class receiving the injection should not rely on it. Instead, define an interface for the things it relies on, and add that interface to the concrete type. It's OK if that interface contains all the concrete type's members.
Example:
public interface IBankAccountAddOnService
{
IBankAccountAddOnResult BuildAddOn();
}
public interface ICreditCardAddOnService : IBankAccountAddOnService
{
int CustomerId { get; }
}
public class CreditCardAddOnService : ICreditCardAddOnService
{
public CreditCardAddOnService(IExternalCreditCardService creditCardService, IRepository repository, ICreditCardAddOn creditCardAddOn)
{
//etc
Does the switch statement violate the Open Closed Principle or is it ok within a factory? If there were many more bank addons in future, the switch statement may become very large?
No, it does not violate OCP in and of itself.
If the list gets very large, you can implement as a map instead, e.g.
var map = new Dictionary<Type,Func<IBankAccountAddOnService>>
{
{ typeof(CreditCardAddOn), () => new CreditCardAddOnService(_creditCardService, _repository, creditCard) },
{ typeof(TravelInsuranceAddOn), () => new TravelInsuranceAddOnService(_travelInsuranceService, travelInsurance) }
}
With the map in place, you can do this:
public IBankAccountAddOnService Create(IBankAccountAddOn addOn)
{
return map[addOn.GetType()]();
}

Initialise a class with a parameterized constructor in the constructor of a Service Class using Castle Windsor

Please note that I have changed the code in the question.
Please see the server side code below (WCF Service):
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace WcfService1
{
public class WindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IGreeting, Greeting>(),
Component.For<IGreetingService, GreetingService>());
}
}
public interface ILanguage
{
string SayHello();
}
public class Spanish : ILanguage
{
public string SayHello()
{
return "Hola";
}
}
public interface IGreeting
{
string SayHello();
}
public class Greeting: IGreeting
{
ILanguage Language;
public Greeting (ILanguage language)
{
Language = language;
}
public string SayHello()
{
return Language.SayHello();
}
}
public interface IGreetingFactory
{
IGreeting Create(ILanguage Language);
}
[ServiceContract]
public interface IGreetingService
{
[OperationContract]
string SayHello(string strLanguage);
}
public class GreetingService : IGreetingService
{
private readonly IGreetingFactory greetingFactory;
private IGreeting greeting;
public GreetingService()
{
}
public GreetingService(IGreetingFactory greetingFactory)
{
// store the factory until we need it
this.greetingFactory = greetingFactory;
}
public string SayHello (string strLanguage)
{
if (strLanguage == "S")
{
ILanguage Language = new Spanish();
Language = new Spanish();
greeting = new Greeting(Language);
}
return greeting.SayHello();
}
}
}
and the client side code below:
ServiceReference1.GreetingServiceClient s1 = new ServiceReference1.GreetingServiceClient();
string greeting = s1.SayHello("S");
ServiceReference1.GreetingServiceClient is a service reference.
The code works as I would expect i.e. Castle Windsor allows me to inject a Greeting into the constructor of the service. However, the Greeting class itself has a parameterized constructor (it requires a Language). In the code above I have to initialise the Greeting (with a language) in the Say Hello method of the service. How can I initialise the Greeting (with a language) in the constructor of the service?
One primary method* of providing run-time, user-driven, or otherwise dynamic dependencies is using factories to create your objects. Castle Windsor provides several different facilities to help with this, or you can use the kernel and implement a factory yourself.
Windsor's facility allows you to provide delegate-based factories, which are just methods for creating an object. You could use that here, but you lose some flexibility in what you can create (if you were to replace the implementation of ICalculator to some other class, you'd have to update this method).
For maximum flexibility, you'll want to use Windsor's interface-based factories. With these, you provide a factory's interface and then Windsor will generate an implementation of it automatically.
Let's use a simplified version of your code above as an example. If you have just have this object:
public class Calculator : ICalculator
{
string Operator;
public Calculator(string operator)
{
Operator=operator;
}
}
And you wanted to pass operator in when you create the object, you'd define a factory like so:
public interface ICalculatorFactory
{
ICalculator Create(string operator);
}
Then you'd register it in your installer:
kernel.Register(Component.For<ICalulatorFactory>().AsFactory());
Now, anywhere you wanted to use a calculator, you'd inject a factory for it, then just invoke Create:
public class CalculatorUseExample
{
private readonly ICalculator addCalculator;
private readonly ICalculator subCalculator;
public CalculatorUseExample(ICalculatorFactory calculatorFactory)
{
addCalculator = calculatorFactory.Create("+");
subCalculator = calculatorFactory.Create("-");
}
}
Note that the name of the operator parameter matters; by default (you can change this if you want), Windsor matches parameters by name.
If we add your CalculatorService class back into the mix, you could use the same pattern:
public interface ICalculatorServiceFactory
{
ICalculatorService Create(string operator);
}
public class CalculatorService : ICalculatorService
{
private readonly ICalculator Calculator;
public CalculatorService(string operator, ICalculatorFactory calculatorFactory)
{
Calculator=calculatorFactory.Create(operator);
}
}
But I don't really like that because why should the service care what the operator is? That's a detail of the calculator. Instead, change the factory to just accept an ICalculator and compose the objects together where you're creating this service:
public interface ICalculatorServiceFactory
{
ICalculatorService Create(ICalculator calculator);
}
public class CalculatorService : ICalculatorService
{
private readonly ICalculator Calculator;
public CalculatorService(ICalculator calculator)
{
Calculator=calculator;
}
}
public class CalculatorServiceUseExample
{
public CalculatorServiceUseExample(ICalculatorServiceFactory calculatorServiceFactory, ICalculatorFactory calculatorFactory)
{
var addCalculator = calculatorFactory.Create("+");
var service = calculatorServiceFactory.Create(addCalculator);
// TODO: use the service
}
}
There are advantages and disadvantages to use this pattern, which I go over in my answer here. Some advantages are that you can protect yourself from future changes and avoid service locator patterns. Disadvantages include a proliferation of interface objects and potentially viral usage of factories (see my first solution above where we had to create another factory).
* There are others of course, this is just the way I'd solve this particular situation because, to me, it indicates intent and is the most discoverable for readers of your code.
Based on your edit regarding WCF and what I understand you're trying to do, I'd implement the service contract like so:
public class CalculatorService : ICalculatorService
{
private readonly ICalculatorFactory calculatorFactory;
private ICalculator calculator;
public CalculatorService(ICalculatorFactory calculatorFactory)
{
// store the factory until we need it
this.calculatorFactory = calculatorFactory;
}
public void ChangeCalculatorServiceClient(string operator)
{
// A new operator, we'll need a new calculator
calculator = calculatorFactory.Create(operator);
}
}
Well, again you've changed your question to include another wrinkle; now you want to instantiate a different type based on a parameter. You can and should still use a factory for this, and this is how I'd go about it:
using Castle.Facilities.TypedFactory;
public class WindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IGreeting, Greeting>(),
Component.For<IGreetingFactory>().AsFactory(),
Component.For<IGreetingService, GreetingService>(),
Component.For<ILanguageFactory, LanguageFactory>());
}
}
public interface ILanguageFactory
{
ILanguage Create(string language);
}
public class LanguageFactory : ILanguageFactory
{
private readonly IKernel kernel;
public LanguageFactory(IKernel kernel)
{
this.kernel = kernel;
}
public ILanguage Create(string language)
{
switch (language)
{
case "S":
return kernel.Resolve<Spanish>();
default:
throw new ArgumentException();
}
}
}
public class GreetingService : IGreetingService
{
private readonly IGreetingFactory greetingFactory;
private readonly ILanguageFactory languageFactory;
private IGreeting greeting;
public GreetingService(IGreetingFactory greetingFactory, ILanguageFactory languageFactory)
{
// store the factory until we need it
this.greetingFactory = greetingFactory;
}
public string SayHello (string strLanguage)
{
var language = languageFactory.Create(strLanguage);
greeting = greetingFactory.Create(language);
return greeting.SayHello();
}
}

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>

Ninject Singleton Factory

I have a interface that is binded to a class. Everything work like excepted. I want to create the class with a constructor injection without passing my kernel everywhere. I want to have a singleton factory for these propose. How can i create one without using the ninject.extensions.factory library.
If you want to create a factory but without using the Factory Extension (not sure why, it's exactly what you need here I think) you can do something like the following:
public class FooFactory : IFooFactory
{
// allows us to Get things from the kernel, but not add new bindings etc.
private readonly IResolutionRoot resolutionRoot;
public FooFactory(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public IFoo CreateFoo()
{
return this.resolutionRoot.Get<IFoo>();
}
// or if you want to specify a value at runtime...
public IFoo CreateFoo(string myArg)
{
return this.resolutionRoot.Get<IFoo>(new ConstructorArgument("myArg", myArg));
}
}
public class Foo : IFoo { ... }
public class NeedsFooAtRuntime
{
public NeedsFooAtRuntime(IFooFactory factory)
{
this.foo = factory.CreateFoo("test");
}
}
Bind<IFooFactory>().To<FooFactory>();
Bind<IFoo>().To<Foo>();
The Factory Extension just does all of that work for you at runtime though. You only need to define the factory interface and the extension creates the implementation dynamically.
Try this code:
class NinjectKernelSingleton
{
private static YourKernel _kernel;
public static YourKernel Kernel
{
get { return _kernel ?? (_kernel = new YourKernel()); }
}
}
public class YourKernel
{
private IKernel _kernel;
public YourKernel()
{
_kernel = InitKernel();
}
private IKernel InitKernel()
{
//Ninject init logic goes here
}
public T Resolve<T>()
{
return _kernel.Get<T>();
}
}

Categories