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>();
}
}
Related
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();
}
}
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.
Code at bottom is from a working WPF sample application that used Autofac for dependency injection.
I want to convert to latest version of MEF instead. I also have NuGet packages CommonServiceLocator (V. 1.3) and Prism.Core, Prism.Mef and Prism.Wpf (all 6.1) installed.
When I do
var provider = ServiceLocator.Current.GetInstance<FriendDataProvider>();
I get an ActivationException from the "Func..." declaration in the constructor of FriendDataProvider.
Can MEF do this at all? If yes, what attribute declarations are required?
[Export]
public class FriendDataProvider
{
private readonly Func<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(Func<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator()) // Factory
{ }
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
Most likely you are looking for MEF ExportFactory class:
https://msdn.microsoft.com/en-us/library/ff382807(v=vs.110).aspx
It'a a mixture of Owned<> and Func<> ideas from AutoFac. Mind that ExportFactory.CreateExport returns ExportLifetimeContext which is Disposable. Disposing the export lifetime context will also dispose the injected part + all its dependencies. ExportFactory behavior is slightly different depending on Instancing mode of the owner part. If the owner class is a singleton ExportFactory will always create you new instance (behaves like Func< Owned< T>> in Autofac), but if you use it in combination with CompositionScopes you'll get behavior similar to Func< T> in AutoFac. See example: http://blogs.microsoft.co.il/bnaya/2013/01/16/mef-20-mini-series-part-6-composition-scoping-and-lifetime-management/
Here is your example re-written using ExportFactories:
[Export]
public class FriendDataProvider
{
private readonly ExportFactory<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(ExportFactory<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator.CreateExport()) // Factory
{
}
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
I have one base generic repository and many class repository that inherits from the base repository. I need too pass string value to the generic repository.
Here is my Generic Repository
public class Repository<T> where T : EntityBase
{
private string SessionId;
public Repository(string sessionId)
{
this.SessionId = sessionId;
}
protected virtual IDbConnection GetCn()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["SalesDb"].ConnectionString);
}
public virtual int Insert(T entity)
{
entity.ChUser = "anders.persson";
entity.ChTime = DateTime.Now;
using (IDbConnection cn = GetCn())
{
cn.Open();
return cn.Insert(entity);
}
}
// MORE CODE
}
}
And the interface
public interface IRepository<T>
{
int Insert(T entity);
}
My Class Repository
public class MarketRepository : Repository<Market>, IMarketRepository
{
}
And the interface
public interface IMarketRepository : IRepository<Market>
{
}
Now i want to pass sessionId to the Generic Repositories constructor.
How can i do that. In this case i have to implement a constructor in every class repository and pass it to the base repository. And the interface dont even know about that constructor.
Here is the Ninject bindings
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
kernel.Bind<ILeadRepository>().To<LeadRepository>();
kernel.Bind<IPricelistRepository>().To<PricelistRepository>();
kernel.Bind<IOptionalGroupRepository>().To<OptionalGroupRepository>();
kernel.Bind<IProductGroupRepository>().To<ProductGroupRepository>();
kernel.Bind<IProductRepository>().To<ProductRepository>();
kernel.Bind<IMarketRepository>().To<MarketRepository>();
kernel.Bind<IModelRepository>().To<ModelRepository>();
kernel.Bind<IOrderRepository>().To<OrderRepository>();
}
You can add it to a binding:
Bind<IMarketRepository>().To<MarketRepository>().WithConstructorArgument("sessionId", "Session ID here");
The sessionId would be a runtime value, so you'll want to pass it to the ctor when resolving.
The syntax to do that is:
var reposetory
= kernel.Get<IMarketRepository>(new ConstructorArgument("sessionId", sessionId));
Given that you don't want to use a Service Locator, calling Get directly, and use ctor injection instead, you can encapsulate that inside a factory.
Configuration:
kernel.Bind<IRepositoryFactory>().To<RepositoryFactory>()
.WithConstructorArgument("kernel", kernel);
Factory:
public class RepositoryFactory : IRepositoryFactory
{
private IKernel _kernel;
public RepositoryFactory(IKernel kernel)
{
_kernel = kernel;
}
public T CreateNew<T>(string sessionId)
{
return
_kernel.Get<T>(new ConstructorArgument("sessionId", sessionId));
}
}
Usage:
var repository = _repositoryFactory.CreateNew<IMarketRepository>(sessionId);
After reading the new documentation on NInject v3 and how to use the Factory Extension, apparently I still don't get it fully since my code throws exceptions all over the place...
I get this Exception, i could paste the whole thing if people would like that but i'll try and keep it short for now.
Error activating IDeployEntityContainer No matching bindings are available,
and the type is not self-bindable.
Here is my code...
The Ninject Bind Module class
class MyNinjectModule : NinjectModule {
public override void Load() {
...
Bind<IDeployEntityFactory>().ToFactory();
Bind<IDeployEntityContainer>().To<DeployEntityContainer>();
...
}
}
The class which uses the factory
class DeployController : IDeployController {
private readonly IDeployEntityFactory _entityFactory;
public DeployController(..., IDeployEntityFactory entityFactory) {
...
}
public void Execute() {
...
//I get the Exception on this line...
_entityFactory.GetDeployEntity<IDeployEntityContainer>();
...
}
}
Factory Interface
public interface IDeployEntityFactory
{
T GetDeployEntity<T>();
}
The Factory Implementation
public class DeployEntityFactory : IDeployEntityFactory
{
private readonly IResolutionRoot _resolutionRoot;
public DeployEntityFactory(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}
public T GetDeployEntity<T>()
{
return _resolutionRoot.Get<T>();
}
}
Behind the scenes Ninject will create a proxy that implements the
specified factory interface and intercept all methods so that the
proxy behaves like...
I understand that I don't have to actually create the implementation my self if i don't need to do something special/custom in the creation of objects inside the factory.
Source: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/
EDIT1:
Just to make sure i leave you with every bit of information you need to see the problem, i'm adding the DeployEntityContainer class/Interface
public abstract class DeployEntityBase : IDeployEntity
{
...
protected readonly IDeployEntityFactory _entityFactory;
protected DeployEntityBase(..., IDeployEntityFactory entityFactory)
{
...
_entityFactory = entityFactory;
...
}
...
}
public class DeployEntityContainer : DeployEntityBase, IDeployEntityContainer
{
...
public DeployEntityContainer(..., IDeployEntityFactory entityFactory)
: base(..., entityFactory)
{
}
}
I ended up just changing the bindings to normal bindings,
Bind<IMyFactory>().To<MyFactory>().InSingletonScope();
and it worked! My first thought was lol, but it makes sense as well.
With the ToFactory() binding it never ever used my implementation of the factory, it just generated one from the defined interface.
Now it uses my implementation. The factory is changed a bit: From newing up the kernel in the factory or injecting it in the constructor, now I inject IResolutionRoot which Get<T>(); my objects.
Here is the new code just for clarification.
class MyNinjectModule : NinjectModule {
public override void Load() {
...
Bind<IDeployEntityFactory>().To<DeployEntityfactory>().InSingletonScope();
Bind<IDeployEntityContainer>().To<DeployEntityContainer>();
...
}
}
public class DeployEntityFactory : IDeployEntityFactory
{
private readonly IResolutionRoot _resolutionRoot;
...
public DeployEntityFactory(..., IResolutionRoot resolutionRoot)
{
...
_resolutionRoot = resolutionRoot;
}
public T GetDeployEntity<T>()
{
return _resolutionRoot.Get<T>();
}
}
If this is not the right way to do it, I hope somebody can shed light on it and notify me with the right way... I imagine #remogloor would know such a thing. :)