Simple Injector Parameter appended to Factory - c#

For brevity, I'll use some short and generalized naming conventions. If I have:
public class Factory : IFactory
{
private readonly string dbConnection;
public Factory(string dbConnection)
{
this.dbConnection= dbConnection;
}
public IDataContext Create() => new DataContext(dbConnection);
}
The Factory class has a field, which is being set by the Constructor. How does Simple Injector support the passing of that parameter? If you implement:
public class Service
{
private IFactory Factory { get; }
public Service(IFactory factory)
{
Factory = factory;
}
public void Save()
{
using(var context = Factory.Create())
context.Insert(...);
}
}
The parameter is never actually passed to or through the Factory when it is initialized or instantiated. When you register the dependencies, it doesn't look it is possible:
ContainerFactory.Register<IFactory, Factory>(Lifestyle.Transient);
I was looking into the IEventHandler interface, that is apart of Simple Injector which looks like it would address this issue, but is that how you're supposed to pass a parameter in this instance?

container.RegisterSingleton<IFactory>(new Factory("constr"));

Related

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();
}
}

Working with Abstract Factory that is injected through DI container

I`m confused about Dependency Injection implementation in one concrete example.
Let's say we have a SomeClass class that has a dependency of type IClassX.
public class SomeClass
{
public SomeClass(IClassX dependency){...}
}
Creation of concrete implementations of IClassX interface depends on runtime parameter N.
With given constructor, I can't configure DI container(Unity is used), because I don't know what implementation of IClassX will be used in runtime.
Mark Seemann in his book Dependency Injection In .Net suggests that we should use Abstract Factory as an injection parameter.
Now we have SomeAbstractFactory that returns implementations of IClassX based on runtime paramater runTimeParam.
public class SomeAbstractFactory
{
public SomeAbstractFactory(){ }
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1();
case 2: return new ClassX2();
default : return new ClassDefault();
}
}
}
SomeClass now accepts ISomeAbstractFactory as an injection parameter:
public class SomeClass
{
public SomeClass(ISomeAbstractFactory someAbstractfactory){...}
}
And that's fine. We have only one composition root where we create the object graph. We configure Unity container to inject SomeAbstractFactory to SomeClass.
But, let's assume that classes ClassX1 and ClassX2 have their own dependencies:
public class ClassX1 : IClassX
{
public ClassX1(IClassA, IClassB) {...}
}
public class ClassX2 : IClassX
{
public ClassX2(IClassA, IClassC, IClassD) {...}
}
How to resolve IClassA, IClassB, IClassC and IClassD dependencies?
1. Injection through SomeAbstractFactory constructor
We can inject concrete implementations of IClassA, IClassB, IClassC and IClassD to SomeAbstractFactory like this:
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD)
{...}
...
}
Unity container would be used in the initial composition root and then use poor man’s DI to return concrete ClassX1 or ClassX2 based on parameter runTimeParam
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1(classA, classB);
case 2: return new ClassX2(classA, classC, classD);
default : return new ClassDefault();
}
}
}
Problems with this approach:
SomeAbstractFactory knows about dependencies that don`t really belong to it.
Deeper object graph would require to change both SomeAbstractFactory constructor and class implementation
DI container would not be used to resolve dependencies, poor man`s DI must be used
2. Explicit call to DI container
Instead of “newing up” ClassX1 or ClassX2, we would resolve them by using a DI container.
public class SomeAbstractFactory
{
public SomeAbstractFactory(IUnityContainer container){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return container.Resolve<IClassX>("x1");
case 2: return container.Resolve<IClassX>("x2");
default : return container.Resolve<IClassX>("xdefault");
}
}
}
Problems with this approach:
DI container is passed into SomeAbstractFactory
DI Resolve method is not used only at the composition root (ServiceLocator anti-pattern)
Is there another more suitable approach?
The example below shows how to do this with Unity. This blog post explains it a little better using Windsor. The underlying concept is exactly the same for each, just slightly different implementation.
I would rather allow my abstract factory to access the container. I view the abstract factory as a way to prevent dependency on the container - my class only depends on IFactory, so it's only the implementation of the factory that uses the container. Castle Windsor goes a step further - you define the interface for the factory but Windsor provides the actual implementation. But it's a good sign that the same approach works in both cases and you don't have to change the factory interface.
In the approach below, what's necessary is that the class depending on the factory passes some argument that allows the factory to determine which instance to create. The factory is going to convert that to a string, and the container will match it with a named instance. This approach works with both Unity and Windsor.
Doing it this way the class depending on IFactory doesn't know that the factory is using a string value to find the correct type. In the Windsor example a class passes an Address object to the factory, and the factory uses that object to determine which address validator to use based on the address's country. No other class but the factory "knows" how the correct type is selected. That means that if you switch to a different container the only thing you have to change is the implementation of IFactory. Nothing that depends on IFactory has to change.
Here's sample code using Unity:
public interface IThingINeed
{}
public class ThingA : IThingINeed { }
public class ThingB : IThingINeed { }
public class ThingC : IThingINeed { }
public interface IThingINeedFactory
{
IThingINeed Create(ThingTypes thingType);
void Release(IThingINeed created);
}
public class ThingINeedFactory : IThingINeedFactory
{
private readonly IUnityContainer _container;
public ThingINeedFactory(IUnityContainer container)
{
_container = container;
}
public IThingINeed Create(ThingTypes thingType)
{
string dependencyName = "Thing" + thingType;
if(_container.IsRegistered<IThingINeed>(dependencyName))
{
return _container.Resolve<IThingINeed>(dependencyName);
}
return _container.Resolve<IThingINeed>();
}
public void Release(IThingINeed created)
{
_container.Teardown(created);
}
}
public class NeedsThing
{
private readonly IThingINeedFactory _factory;
public NeedsThing(IThingINeedFactory factory)
{
_factory = factory;
}
public string PerformSomeFunction(ThingTypes valueThatDeterminesTypeOfThing)
{
var thingINeed = _factory.Create(valueThatDeterminesTypeOfThing);
try
{
//This is just for demonstration purposes. The method
//returns the name of the type created by the factory
//so you can tell that the factory worked.
return thingINeed.GetType().Name;
}
finally
{
_factory.Release(thingINeed);
}
}
}
public enum ThingTypes
{
A, B, C, D
}
public class ContainerConfiguration
{
public void Configure(IUnityContainer container)
{
container.RegisterType<IThingINeedFactory,ThingINeedFactory>(new InjectionConstructor(container));
container.RegisterType<IThingINeed, ThingA>("ThingA");
container.RegisterType<IThingINeed, ThingB>("ThingB");
container.RegisterType<IThingINeed, ThingC>("ThingC");
container.RegisterType<IThingINeed, ThingC>();
}
}
Here's some unit tests. They show that the factory returns the correct type of IThingINeed after inspecting what was passed to its Create() function.
In this case (which may or may not be applicable) I also specified one type as a default. If nothing is registered with the container that exactly matches the requirement then it could return that default. That default could also be a null instance with no behavior. But all of that selection is in the factory and container configuration.
[TestClass]
public class UnitTest1
{
private IUnityContainer _container;
[TestInitialize]
public void InitializeTest()
{
_container = new UnityContainer();
var configurer = new ContainerConfiguration();
configurer.Configure(_container);
}
[TestCleanup]
public void CleanupTest()
{
_container.Dispose();
}
[TestMethod]
public void ThingINeedFactory_CreatesExpectedType()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.B);
Assert.AreEqual(output, typeof(ThingB).Name);
}
[TestMethod]
public void ThingINeedFactory_CreatesDefaultyTpe()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.D);
Assert.AreEqual(output, typeof(ThingC).Name);
}
}
This same factory can be implemented using Windsor, and the factory in the Windsor example could be done in Unity.

Inject object using MEF with information about destination object

I am looking for a way to inject a logging object which wraps a log4net logger into various objects using MEF. The problem I currently have is that the logging object requires the type of the object it is a member of. I could get round this problem by setting the type property on the logging object within the constructor of the containing object, however this leaves the onus of setting the type on the developer, and there is no compile time restriction I can think of to enforce this.
I there a way to specify that when the logging object is generated by MEF and injected, its constructor parameter is set to the type of the target class of the injection?
My logger implements an interface
public interface ILogger
{
Type Type { get; }
}
An Example of the concrete implementation of this is
[Export(typeof(Ilogger))]
public class SimpleLogger : ILogger
{
public SimpleLogger(Type typeOfObjectToLogFor)
{
this.Type = typeOfObjectToLogFor
}
public Type Type { get; }
public void Info(string message)
{
//log the messsage including the type information
}
}
and it is currently consumed not using MEF as:
public class ExampleObject
{
private readonly ILogger logger = new SimpleLogger(typeof(ExampleObject));
public ExampleObject(){}
public void MethodThatLogs()
{
logger.Info("MethodThatLogs called");
}
}
and what I would like to do is inject it using constructor injection:
public class ExampleObject
{
private readonly ILogger logger;
[ImportingConstructor]
public ExampleObject(Ilogger injectedLogger)
{
logger = injectedLogger;
}
public void MethodThatLogs()
{
logger?.Info("MethodThatLogs called");
}
}
I could do all this with lazy evaluated reflection, but it feels like something that should be possible from a decent DI container, and hopefully that means that MEF will support it, cam anyone help?
By default, specifying an [Export] attribute, you're setting the PartCreationPolicy to Shared, which means that the container will create a singleton for your export - your logger.
But I suggest you to export not a class but a factory method that will accept one argument and create the logger for you.
class LoggerFactory
{
[Export("GetLogger")]
public ILogger GetLogger(Type type)
{
return new SimpleLogger(type);
}
}
class ExampleObject
{
private readonly ILogger logger;
[ImportingConstructor]
public ExampleObject([Import(ContractName = "GetLogger", AllowDefault = true)]Func<Type, ILogger> loggerCreator)
{
logger = loggerCreator?.Invoke(this.GetType());
}
}

Always Valid Entity and Constructor Injection

Giving the following sample:
class Customer
{
ICustomerRepository repository;
private string name;
public Customer(string name, ICustomerRepository repository)
{
Name = name;
this.repository= repository;
}
public string Name
{
get {return name;}
set
{
if(String.IsNullOrWhiteSpace(value))
throw new ArgumentException();
name = value;
}
}
}
I'm using ninject IoC.
I abstract ninject container in an IFactory interface that has Get<>() method, so i want use only constructor injection. I do that because i don't want use [Inject] attributes.
I want follow the always valid entity principle.
In this scenario i can't do that because i have a parameter on constructor. There is an another approach to do that?
Edit:
I abstract ninject container in an IFactory interface that has Get<>() method, so i want use only constructor injection. I do that because i don't want use [Inject] attributes.
Abstraction of my the container:
interface IFactory
{
T Get<T>();
IEnumerable<T> GetAll<T>();
}
Implementation:
class ApplicationFactory : IFactory
{
private readonly IKernel ninjectKernel = ApplicationNinjectKernel.BuildNew();
public T Get<T>()
{
return ninjectKernel.Get<T>();
}
public IEnumerable<T> GetAll<T>()
{
return ninjectKernel.GetAll<T>();
}
}
ApplicationNinjectKernel.BuildNew() creates and return a new StandarKernel() with the binds..
ConstructorArgument sounds bad to me. With this approach i will put some ugly thing on my code and also will miss type checking at project time. :/
If you are trying to use Ninject to resolve using a given customer name, you can do it like this:
var customer = kernel.Get<Customer>(new ConstructorArgument("name", "Bob"));
This also requires that you followed the convention of binding your ICustomerRepository in the Ninject Module and loaded it into the Ninject Kernel. Example:
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}

resolving constructor dependency at runtime (without attributes)

I am using Unity for dependency injection and I want to control at runtime, which particular type is resolved and passed into a constructor as a dependency.
I have an interface:
public interface IDatabase
{
void DoSomething();
}
That is implemented by two classes:
public class SQLDatabase : IDatabase
{
public void DoSomething()
{
//Do Something on a SQL server database...
}
}
public class OracleDatabase : IDatabase
{
public void DoSomething()
{
//Do Something on an Oracle database...
}
}
A third class has a dependency on IDatabase
public class DataService: IDataService
{
public DataService(IDatabase database)
{
database.DoSomething();
}
}
The module registers each class with Unity and the two IDatabase types are given specific names so that they can be differentiated:
container.RegisterType<IDatabase, SQLDatabase>("SQLDatabase");
container.RegisterType<IDatabase, OracleDatabase>("OracleDatabase");
container.RegisterType<IDataService, DataService>();
I need to create an instance of a Consumer, at which point I want to specify which of the two types that implement IDatabase are to be used/injected by Unity, but I don't know how to tell Unity which specific type to construct/resolve? I guess I want something like this (Pseudo code):
public class Consumer
{
IDataService dataService = null;
public Consumer(string runtimeChoice)
{
if (runtimeChoice == "SQLSERVER")
{
dataService = _container.Resolve<IDataService>("SQLDatabase");
}
else if (runtimeChoice == "Oracle")
{
dataService = _container.Resolve<IDataService>("OracleDatabase");
}
}
}
So, how do I tell Unity to resolve the IDatabase type, using the specific named type, and pass it into the constructor of dependent objects, but doing it at runtime?
There are two things I would change, I would try to ensure those magic strings were handled as close to their source as possible and I would try to ensure my code was container agnostic.
I would have the following interface:
public interface IDataServiceFactory
{
IDataService CreateSqlDataService();
IDataService CreateOracleDataService();
}
With an implementation like so:
public class DataServiceFactory : IDataServiceFactory
{
private readonly Func<IDataService> _sqlDataServiceFactory;
private readonly Func<IDataService> _oracleDataServiceFactory;
public DataServiceFactory(Func<IDataService> sqlDataServiceFactory, Func<IDataService> oracleDataServiceFactory)
{
_sqlDataServiceFactory = sqlDataServiceFactory;
_oracleDataServiceFactory = oracleDataServiceFactory;
}
public IDataService CreateSqlDataService()
{
return _sqlDataServiceFactory();
}
public IDataService CreateOracleDataService()
{
return _oracleDataServiceFactory();
}
}
I would then register this with your IUnityContainer like so:
_container.RegisterType<IDataService, DataService>("SQLDataService",
new InjectionConstructor(new ResolvedParameter<IDatabase>("SQLDatabase")));
_container.RegisterType<IDataService, DataService>("OracleDataService",
new InjectionConstructor(new ResolvedParameter<IDatabase>("OracleDatabase")));
_container.RegisterType<IDataServiceFactory, DataServiceFactory>(new InjectionConstructor(
new ResolvedParameter<Func<IDataService>>("SQLDataService"),
new ResolvedParameter<Func<IDataService>>("OracleDataService"));
Now whatever was previously creating your Consumer instances should now have a dependency on IDataServiceFactory and should handle the runtime value to call the correct method CreateSqlDataService() or CreateOracleDataService().
All of your runtime code is now container agnostic and the magic strings are handled right next to their source.
I was able to resolve the correct type using a DependencyOverride, which itself obtained the required type from the unity container. So the consumer becomes:
public class Consumer
{
IDataService dataService = null;
public Consumer(string runtimeChoice)
{
DependencyOverride<IDatabase> dependency = null;
if (runtimeChoice == "SQLSERVER")
{
dependency = new DependencyOverride<IDatabase>
(Container.Resolve<IDatabase>("SQLDatabase"));
}
else if (runtimeChoice == "Oracle")
{
dependency = new DependencyOverride<IDatabase>
(Container.Resolve<IDatabase>("OracleDatabase"));
}
dataService = _container.Resolve<IDataService>(dependency);
}
}
I have a similar requirement where I need to resolve a 'widgetbuilder' type at runtime. In my Unity Configuration I register my two types of widget builders:-
container.RegisterType<IWidgetBuilder, SinglePointWidgetBuilder>("SinglePointWidgetBuilder");
container.RegisterType<IWidgetBuilder, CurrentVsTargetWidgetBuilder>("CurrentVsTargetWidgetBuilder");
I then resolve them at runtime by:-
var container = UnityConfig.GetConfiguredContainer();
var widgetBuilder = container.Resolve<IWidgetBuilder>("SinglePointWidgetBuilder");

Categories