I need to provide some global scope to a ninject module, and figure that it would be best to inject this in via a module.
I'm currently scanning assemblies for modules, and as such, can't determine how to provide these arguments (cleanly).
I have a console app, and I want to choose the implementation of a type based on the arguments to the application.
The issue is that those types have a dependency on the specific deserialisation of those arguments, which is determined at lookup time.
What I'd like to do is something like this:
public class Module : MyNinjectModule<Module>
{
private enum FictionalEnum
{
FirstType,
SecondType
}
private string[] _args;
private FictionalEnum Type
{
get
{
return IsFirstType(_args)
? FictionalEnum.FirstType
: FictionalEnum.SecondType;
}
}
public Module(string[] rawArgs)
{
_args = rawArgs;
}
protected override void LoadCustomBindings()
{
Bind<IBaseType>().To<FirstImpl>()
.When(req => this.Type == FictionalEnum.FirstType);
Bind<IBaseType>().To<SecondImpl>()
.When(req => this.Type == FictionalEnum.SecondType);
}
}
Does anyone have any suggestions for this?
In my opinion this logic does not belong into a module. I would either inject all the instances and then decide in the application which of the instances to take or inject a factory and let the factory create the correct type depending on the argument.
Related
I'm trying to understand how to use TypedFactoryFacility to create an abstract factory, and I have it working at a basic level, however I don't fully understand how to scale it with runtime dependencies
Suppose I have a service that needs to be created at runtime:
public interface IRuntimeService {
void DoThing();
}
with the following implementation
public class RuntimeService : IRuntimeService {
public void DoThing() {
// Do some work
}
}
To create my IRuntimeService, I've created an abstract factory
public interface IRuntimeServiceFactory {
IRuntimeService CreateService();
}
In my Castle installer, I'm using the TypedFactoryFacility to register my class and abstract factory.
public class TypeInstaller : IWindsorInstaller {
public void Install(IWindsorContainer container, IConfigurationStore store) {
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IRuntimeService>().ImplementedBy<RuntimeService>());
container.Register(Component.For<IRuntimeServiceFactory>().AsFactory());
}
Then in my class that will be using the service, I can use the factory to create new service instances at runtime.
var myService = m_ServiceFactory.CreateService();
Everything above works perfectly, however I'm running into a problem when my RuntimeService class needs to be injected with a dependency chain itself that include runtime parameters.
To expand the example above, suppose I have a new runtime dependency
public interface IRuntimeDependency {
void DoWork();
}
implemented by a class that takes a runtime string value through the constructor
public class RuntimeDependency : IRuntimeDependency {
private readonly string m_Param;
public RuntimeDependency(string param) {
m_Param = param;
}
public void DoWork() {
// Do work involving the param
}
}
And the previously defined service class now needs a reference to the dependency
public class RuntimeService : IRuntimeService {
private readonly IRuntimeDependency m_Dep;
public RuntimeService(IRuntimeDependency dep) {
m_Dep = dep;
}
public void DoThing() {
// Do some work involving the dependency
m_Dep.DoWork();
}
}
How do I now I create instances of my service using the TypedFactoryFacility?
I would expect do just be able to change my factory method to look like
IRuntimeService CreateService(string param);
but Windsor throws an error 'Could not resolve non-optional dependency for parameter 'param' type 'System.String'.
Windsor knows how to create an IRuntimeDependency if I give it a string, and it knows how to create a IRuntimeService if I give it the dependency, so why can't it directly create a IRuntimeService with the string param?
I can make it work by having two distinct factory methods
IRuntimeService CreateService(IRuntimeDependency dep);
IRuntimeDependency CreateDependency(string param);
and creating the dependency, manually myself
var dep = m_ServiceFactory.CreateDependency(param);
var myService = m_ServiceFactory.CreateService(dep );
^^^This works, but the whole point of using a container is so that it will take care of assembling new objects for me. This is a relatively simple example involving only one dependency, but it would easily grow out of control with a more complex object graph.
I could of course create my own factory implementations, but that also nullifies the benefit of using the TypedFactoryFacility which is supposed to create the abstract factory implementations for you. I have a hard time believing there's not an existing solution to this problem but the Windsor examples don't contain any chained run-time dependencies.
I don't think using a FactoryComponentSelector is the correct approach because there's only one possible path to create the RuntimeService instance. It should be able to auto-resolve.
In many or most cases, an object resolved by the container depends on implementations of other interfaces which are also resolved by the container. So as long as all of the interfaces have registered implementations, the container can resolve the entire dependency chain.
But in this case RuntimeDependency depends on a string, which isn't something the container can resolve.
public RuntimeDependency(string param) {
m_Param = param;
}
In this case you can use the DependsOn method to explicitly provide a value to fulfill that dependency.
container.Register(Component.For<IRuntimeDependency, RuntimeDependency>()
.DependsOn(Dependency.OnValue("param","whatEverTheValueIs")));
That value can, of course, come from configuration or wherever else. I use this a lot with SQL connection strings.
It is possible using DynamicParameters.
container.Register(Component.For<IRuntimeService>()
.ImplementedBy<RuntimeService>()
.LifestyleTransient()
.DynamicParameters((k, d) => {
d["dep"] = new RuntimeDependency((string)d["param"]);
}));
Keep in mind that the dictionary keys have to match the parameter names in the CreateService method and RuntimeService constructor.
Edit: You should also make it LifestyleTransient if you intend to create a new instance each time the factory method is called. (The default is singleton)
It seems that what I am asking for is not possible by design.
See this other SO answer.
https://stackoverflow.com/a/3905496/2029835
I have an abstract factory which creates some service represented by IService interface. In the factory I have two Create methods, because at one of them I allow the consumer to pass an existing IServiceLogger instance to be used by the constructed service tree.
public interface IMyServiceFactory {
IMyService Create(IServiceLogger loggerInstance);
IMyService Create();
}
Because an IServiceLogger should be shared among the service tree, I use the InCallScope when binding it to a concrete implementation.
How can I implement this scenario with Ninject? I've tried the following approaches.
1. Manually create a factory implementation
internal class MyServiceFactory : IMyServiceFactory {
private IResolutionRoot _kernel;
public MyServiceFactory
public IMyService Create(IServiceLogger loggerInstance) {
// what should go here? how can I pass the existing instance to Ninject Get method and make Ninject to use it for the whole resolution tree, just as it were created by Ninject and used as InCallScope?
}
// this one is trivial...
pulbic IMyService Create() {
return _kernel.Get<IMyService>();
}
}
UPDATE
Actually I've found a messy and not too safe way for this. I can get the current bindings via GetBindings, then Rebind IServiceLogger ToConstant, then Get the IMyService instance, and finally restore the original bindings with AddBinding. I don't like it, it feels stinky and what's worse, it's not thread-safe, because another thread can request for a IMyService in the middle of this code and hence use the local temporary binding.
2. Use Ninject.Extensions.Factory
Just use the ToFactory binding, but that's not working, because it just tries to use the parameter as a simple constructor argument (if applicable), and not as an object for the whole resolution tree.
I would give more control to the Kernel of Ninject and do not create a class for the factory at all.
And use Func binding in Ninject like this:
Bind<Func<IMyService>>().ToMethod(s => CreateService);
By binding of the ILoggerService or not binding this you can controll centrally whether you have logger or not in your service.(try by just comment it out)
Here implementation of the Bootstrapper:
public class Bootstrapper
{
private IKernel _kernel = new StandardKernel();
public Bootstrapper()
{
_kernel.Bind<MyStuff>().ToSelf();
_kernel.Bind<IServiceLogger>().To<ServiceLogger>();
_kernel.Bind<IMyService>().To<MyService>();
_kernel.Bind<Func<IMyService>>().ToMethod(s => CreateService);
}
public IKernel Kernel
{
get
{
return _kernel;
}
set
{
_kernel = value;
}
}
private IMyService CreateService()
{
if(_kernel.GetBindings(typeof(IServiceLogger)).Any())
{
return _kernel.Get<IMyService>(new ConstructorArgument("logger", _kernel.Get<IServiceLogger>()));
}
return _kernel.Get<IMyService>();
}
}
Implementation of consumer class for the factory:
internal class MyStuff
{
private readonly Func<IMyService> _myServiceFactory;
public MyStuff(Func<IMyService> myServiceFactory)
{
_myServiceFactory = myServiceFactory;
_myServiceFactory.Invoke();
}
}
Simple implementation of MyService:
internal class MyService
:IMyService
{
public MyService()
{
Console.WriteLine("with no parameters");
}
public MyService(IServiceLogger logger)
{
Console.WriteLine("with logger parameters");
}
}
Simple ServiceLogger:
internal class ServiceLogger
:IServiceLogger
{
public ServiceLogger()
{
}
}
internal interface IServiceLogger
{
}
IMPORTANT UPDATE
While my original answer gave me a working solution, by an accidental InteliSense navigation I've just found that there is a built-in tool for exactly this issue. I just have to use the built-in TypeMatchingArgumentInheritanceInstanceProvider which does this, and even more, because there are no more needs for naming conventions due to the parameter type matching.
It would be good to have a more detailed documentation about these options, or maybe it's just me who can't find it currently.
ORIGINAL ANSWER
I tried a few ways, and ended up with a slightly different, kind of a convention based approach utilizing Ninject's context parameter inheritance.
The convention is used at constructor argument naming through the dependency tree. For example whenever an IServiceLogger instance is injected to a service class, the argument should be called serviceLogger.
With the above convention in mind, I've tested the following approach. Firstly I've implemented a custom instance provider for the factory extension. This custom provider overrides the mechanism for creating constructor parameters for the context to let the developer specify several named arguments which should be set as inherited. This way all the parameters with the specified names will inherit through the whole request graph during the get operation.
public class ParameterInheritingInstanceProvider : StandardInstanceProvider
{
private readonly List<string> _parametersToInherit = new List<string>();
public ParameterInheritingInstanceProvider(params string[] parametersToInherit)
{
_parametersToInherit.AddRange(parametersToInherit);
}
protected override IConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
{
var parameters = methodInfo.GetParameters();
var constructorArgumentArray = new IConstructorArgument[parameters.Length];
for (var i = 0; i < parameters.Length; ++i)
constructorArgumentArray[i] = new ConstructorArgument(parameters[i].Name, arguments[i], _parametersToInherit.Contains(parameters[i].Name));
return constructorArgumentArray;
}
}
Then after at binding configuration I just threw it in with the corresponding parameter name.
kernel.Bind<IMyServiceFactory>().ToFactory(() => new ParameterInheritingInstanceProvider("serviceLogger"));
Finally I reviewed parameter naming, and for exampled changed loggerInstance in the factory interface to serviceLogger to match the convention.
This solution is still not the nicest one as it has several limitations.
It is error prone. One can make bugs which are hard to track by not keeping the naming convention, because currently it silently fails if the convention does not match. This could be improved probably, I'll think about it later.
It handles only constructor injection, however this should not be a big issue as that's the suggested technique. For example I almost never do other kind of injections.
I realise this was asked a long time ago but I was looking to do the same sort of thing myself and finally worked out that you can use the IParameter array passed to the Get() method to specify a ContructorArgument to use only for the current Get() call. This allowed me to use a specific constructor value when creating a Hangfire Job allowing the Hangfire job to use a different database connection on each invocation if required.
EnvironmentName forcedEnv = new EnvironmentName() { Name = dbName };
// For this instantiation, set the 'envName' parameter to be the one we've specified for this job
var instance = ResolutionExtensions.Get((IResolutionRoot) _kernel, jobType,
new IParameter[] {new ConstructorArgument("envName", forcedEnv, true)});
return instance;
By setting the shouldInherit value to true you can ensure the value gets passed down the resolution chain. So it get's passed to any objects in the dependency tree that use that argument (but only for this particular instantiation).
I am just beginning to learn about IoC and Dependency Injection. I am planning on doing a MonoTouch project and wanted to use TinyIoC but I wanted to test it out first. I'm creating a dummy credit card processing console app and I'm having trouble with how to configure TinyIoC since I have multiple implementations of my interface. This is my test app.
Interface:
public interface IPaymentProcessor
{
void ProcessPayment(string cardNumber);
}
Two Implementations of the interface:
VisaPaymentProcessor
public class VisaPaymentProcessor : IPaymentProcessor
{
public void ProcessPayment(string cardNumber)
{
if (cardNumber.Length != 13 && cardNumber.Length != 16)
{
new ArgumentException("Card Number isn't the correct length");
}
// some code for processing payment
}
}
AmexPaymentProcessor
public class AmexPaymentProcessor : IPaymentProcessor
{
public void ProcessPayment(string cardNumber)
{
if (cardNumber.Length != 15)
{
new ArgumentException("Card Number isn't the correct length");
}
// some code for processing the payment
}
}
Simple stuff. Now I have a class that accepts the interface as a parameter in the constructor....
CreditCardProcessor
public class CreditCardProcessor
{
public IPaymentProcessor PaymentProcessor { get; set; }
public CreditCardProcessor(IPaymentProcessor processor)
{
this.PaymentProcessor = processor;
}
public void ProcessPayment(string creditCardNumber)
{
this.PaymentProcessor.ProcessPayment(creditCardNumber);
}
}
My console app looks like this....
class Program
{
static void Main(string[] args)
{
TinyIoCContainer.Current.AutoRegister();
var creditCardProcessor = TinyIoCContainer.Current.Resolve<CreditCardProcessor>();
creditCardProcessor.ProcessPayment("1234567890123456"); // 16 digits
}
}
So I am trying to figure out how to tell the Resolve which implementation of the interface to pass to the constructor. If I run this code, I will always use the VisaPaymentProcessor implementation.
So how can I make TinyIoC pass the AmexPaymentProcessor implementation to the constructor rather than the VisaPaymentProcessor(which seems to be the default)?
I haven't used TinyIoC myself, but I suspect you want:
TinyIoCContainer.Current.Register(typeof(IPaymentProcessor),
typeof(AmexPaymentProcessor));
(If you want to use Amex.)
There are various other Register overloads available, including one which takes a name to use, which may be useful when you resolve. It really depends on what you're trying to achieve, which isn't terribly clear from the question.
I'm not really sure what you're trying to achieve here, but if you have multiple implementations of an interface and you want a specific one then you need to register each one with a name, or use RegisterMultiple, which uses the type name for a name, then resolve using that name and use that along with NamedParameterOverloads to specify which one you want.
It sounds more like though that you might want some kind of ProcessorFactory, or a facade of some kind, that takes a dependency on IEnumerable and supplies/acts as a facade for the correct implementation depending on the number passed in.
Something like this in Global.asax or application entry (Modified for your example)
const string nameTrim = "paymentprocessor";
var type = typeof(IPaymentProcessor);
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(x => type.IsAssignableFrom(x) && x.IsClass).ToList()
.ForEach(t =>
{
var name = t.Name.ToLower();
if (name.EndsWith(nameTrim))
name = name.Substring(0, name.Length - nameTrim.Length);
TinyIoCContainer.Current.Register(type, t, name);
});
It finds alla implementations of IPaymentProcessor and registers them with classname
(-PaymentProcessor, if the classname ends with PaymentProcessor)
Then I can resolve for example "AmexPaymentProcessor" with
IPaymentProcessor handler;
if (TinyIoCContainer.Current.TryResolve("amex", out handler))
{
response = handler.ProcessPayment(cardNumber);
}
In my program I have multiple instances of a specific class Tracer (A1,B2,C3 etc). Using a listbox called tracerListBox, the user will determine which tracer they want to use.
Lets say each tracer has a constructor named family.
I know that if I wanted to access the family of, say, A1 I would simply type:
A1.family
However, I want to write code that accomplishes something like this:
tracerListBox.Text.family
Is there a way to pass a user-determined value to a constructor? I essentially want the user to determine which instance of Class Tracer to use and then use that information to pull all of the information about that specific tracer.
Thanks in advance for any assistance you can provide.
What you are looking for is a factory method, sometimes also called a virtual constructor (which is not technically correct, because it's neither a constructor nor a virtual method).
Instead of calling a constructor, you call a static method that calls a constructor of the class determined by the arguments passed in.
interface ITracer {
void Trace(string s);
}
class TracerA : ITracer {
public void Trace(string s) {
// ...
}
}
class TracerB : ITracer {
public void Trace(string s) {
// ...
}
}
class TracerFactory {
public static ITracer Make(string name) {
if (name.Equals("A")) return new TracerA();
if (name.Equals("B")) return new TracerB();
throw new ApplicationException("Unknown: "+name);
}
}
Much of the detail to actually make a decision is missing from your question. However, we can point you in the general directions that may answer your question.
Reflection would definitely help. Look at object.GetType() to start.
Check out different Dependency Injection or Inversion of Control (IOC) libraries. They may be just what you need.
Are you looking for something like this:
string myType = "MyNamespace." + tracerListBox.Text + ", MyAssembly";
var = Type.GetType( myType );
var property = t.GetProperty("family", BindingFlags.Static);
I'm trying to remove a Service Locator from an abstract base class, but I'm not sure what to replace it with. Here is a psuedo-example of what I've got:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
The problem with this is that the instanciator of a derived class doesn't know what bindings the kernel must have in order to keep MySpecialResolver from throwing an exception.
This might be intrinsicly intractable because I don't know from here which types I'll have to resolve. The derived classes are responsible for creating the types parameter, but they aren't hardcoded anywhere. (The types are based on the presence of attributes deep within the derived class's composition hierarchy.)
I've trying to fix this with lazy loading delegates, but so far I haven't come up with a clean solution.
Update
There are really two issues here, one is that the IoC container is passed to the controller, acting as a service locator. This is easy to remove--you can move the location up or down the call stack using all sorts of techniques.
The second issue is the difficult one, how can you ensure that the controller has the necessary services when the requirements aren't exposed until runtime. It should have been obvious from the start: you can't! You will always be dependent upon either the state of the service locator or contents of a collection. In this particular case no amount of fiddling will ever resolve the problem described in this article with staticly typed dependencies. I think that what I'm going to end up doing is passing a Lazy array into the controller constructor and throwing an exception if a required dependency is missing.
I agree with #chrisichris and #Mark Seemann.
Ditch the kernel from the controller. I'd switch your resolver composition a little bit so that your controller can remove the dependency on the IoC container and allow the resolver to be the only item that worries about the IoC container.
Then I would let the resolver get passed into the constructor of the controller. This will allow your controller to be far more testable.
For example:
public interface IMyServiceResolver
{
List<IMyServiceInterface> Resolve(Type[] types);
}
public class NinjectMyServiceResolver : IMyServiceResolver
{
private IKernal container = null;
public NinjectMyServiceResolver(IKernal container)
{
this.container = container;
}
public List<IMyServiceInterface> Resolve(Type[] types)
{
List<IMyServiceInterface> services = new List<IMyServiceInterface>();
foreach(var type in types)
{
IMyServiceInterface instance = container.Get(type);
services.Add(instance);
}
return services;
}
}
public abstract class MyController : Controller
{
private IMyServiceResolver resolver = null;
public MyController(IMyServiceResolver resolver)
{
this.resolver = resolver;
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
Now your controller isn't coupled to a specific IoC container. Also your controller is much more testable since you can mock the resolvers and not require an IoC container at all for your tests.
Alternatively, if you don't get to control when a controller is instantiated, you can modify it slightly:
public abstract class MyController : Controller
{
private static IMyServiceResolver resolver = null;
public static InitializeResolver(IMyServiceResolver resolver)
{
MyController.resolver = resolver;
}
public MyController()
{
// Now we support a default constructor
// since maybe someone else is instantiating this type
// that we don't control.
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
You would then call this at your application start up to initialize the resolver:
MyController.InitializeResolver(new NinjectMyServiceResolver(kernal));
We did this to handle elements created in XAML who require dependencies resolved but we wanted to remove Service Locator like requests.
Please excuse any syntactical errors :)
I'm writing a blog post series on the topic of refactoring an MVVM application with Service Locator calls in the view models you might find interesting. Part 2 is coming soon :)
http://kellabyte.com/2011/07/24/refactoring-to-improve-maintainability-and-blendability-using-ioc-part-1-view-models/
Maybe you should just do away the Kernel, Types and MySpecialResolver and let the subclasses call DoActions with the IMyServiceInterface instances they need as argument directly. And let the subclasses decide how they get to these instances - they should know best (or in case they don't know which exactly the one who ever decides which instances of IMyServiceInterface are needed)
I would have liked to have a bit more information before posting this answer, but Kelly put me on the spot. :) Telling me to put my code where my mouth is, so to speak.
Like I said in my comment to Kelly, I disagree with moving the resolver/locator from a static implementation to an injected implementation. I agree with ChrisChris that the dependencies the derived type needs should be resolved in that class and not delegated to the base class.
That said, here is how I would remove the service location...
Create Command Interface
First of all I would create a command interface for the specific implementation. In this case the types sent with the DoActions method are generated from attributes, so I would create an IAttributeCommand. I am adding a Matches method to the command in order to declare the command for use by certain types.
public interface IAttributeCommand
{
bool Matches(Type type);
void Execute();
}
Add Command Implementations
To implement the interface, I pass in the specific dependencies I need to execute my command (to be resolved by my container). I add a predicate to my Matches method, and define my Execute behavior.
public class MyTypeAttributeCommand : IAttributeCommand
{
MyDependency dependency;
SomeOtherDependency otherDependency;
public MyTypeAttributeCommand (MyDependency dependency, ISomeOtherDependency otherDependency)
{
this.dependency = dependency;
this.otherDependency = otherDependency
}
public bool Matches(Type type)
{
return type==typeof(MyType)
}
public void Execute()
{
// do action using dependency/dependencies
}
}
Register Commands with Container
In StructureMap (use your favorite container), I would register the array like so:
Scan(s=>
{
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IAttributeCommand>();
s.WithDefaultConventions();
}
Select and Execute Commands Based on Type
Finally, on the base class, I define an IAttributeCommand array in my constructor arguments to be injected by the IOC container. When the derived type passes in the types array, I will execute the correct command based on the predicate.
public abstract class MyController : Controller
{
protected IAttributeCommand[] commands;
public MyController(IAttributeCommand[] commands) { this.commands = commands); }
protected void DoActions(Type[] types)
{
foreach(var type in types)
{
var command = commands.FirstOrDefault(x=>x.Matches(type));
if (command==null) continue;
command.Execute();
}
}
}
If you multiple commands can handle one type, you can change the implementation: commands.Where(x=>x.Matches(type)).ToList().ForEach(Execute);
The effect is the same, but there is a subtle difference in how the class is constructed. The class has no coupling to an IOC container and there is no service location. The implementation is more testable as the class can be constructed with its real dependencies, with no need to wire up a container/resolver.