Suppose I have a class
public class Foo()
{
public Foo(Bar bar){}
public Foo():this(Bar.Default){}
}
I want StructureMap to use the first constructor overload when bar can be resolved by the container, but the second when it cannot.
How can I configure the container to do this (both in general, and specifically for the Foo class?)
Foo has a dependency on Bar so you should model that as a single constructor, it is up to your container to inject the correct implementation of Bar.
So when you configure your container you should apply detection of when bar cannot be resolved and the default should be used
Container cont = new Container(c =>
{
if (useDefaultBar)
{
c.For<IBar>().Use<Bar>(Bar.Default);
}
else
{
c.For<IBar>().Use<Bar>();
}
});
Related
I have used Castle.DynamicProxy to create an interceptor that implements IInterceptor. This interceptor does some work related with logging.
I have successfully injected this into multiple classes using the default Microsoft Dependency Injection and I also was able to do so using Autofac.
Microsoft Dependency Injection:
public static void AddLoggedScoped<TService, TImplementation>(this IServiceCollection pServices)
where TService : class
where TImplementation : class, TService
{
pServices.TryAddScoped<IProxyGenerator, ProxyGenerator>();
pServices.AddScoped<TImplementation>();
pServices.TryAddTransient<LoggingInterceptor>();
pServices.AddScoped(provider =>
{
var proxyGenerator = provider.GetRequiredService<IProxyGenerator>();
var service = provider.GetRequiredService<TImplementation>();
var interceptor = provider.GetRequiredService<LoggingInterceptor>();
return proxyGenerator.CreateInterfaceProxyWithTarget<TService>(service, interceptor);
});
}
Autofac Dependency Injection:
builder.RegisterType<DITest>( ).As<IDITest>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggingInterceptorAdapter<LoggingInterceptor>));
Despite this I would also like to inject it in classes dynamically instantiated (for instances, classes that are instantiated accordingly to a value - factory pattern). My factory instantiates different concretizations of an interface depending on a value provided by parameter. Something along these lines:
public IApple Create(string color)
{
IApple fruit;
switch (color)
{
case "green":
fruit = new GreenApple();
break;
case "red":
fruit = new RedApple();
}
return fruit;
}
The interface IFruit looks like these:
public interface IFruit
{
void Cut();
void Eat();
string GetNutrionalInfo();
}
What I am trying to achieve is a way to inject/add an interceptor to the concretization of RedApple() that would allow me to know when methods such as redApple.Cut() are called.
What is the best way to do so? I was under the impression that Autofac would allow this, but I have not been successful.
What you will need to do is update your factory to use service location instead of directly constructing things. Basically, instead of using new, you'll need to use Autofac or Microsoft DI (assuming Autofac is configured as the backing container) to resolve the thing.
First, whenever you need your factory, make sure you are injecting it and not just calling new. Everything involved in this chain needs to go through Autofac.
public class UsesTheFactory
{
private IFactory _factory;
public UsesTheFactory(IFactory factory)
{
this._factory = factory;
}
}
You will, of course, need to register the thing that uses the factory.
builder.RegisterType<UsesTheFactory>();
Next, inject the lifetime scope into the factory and use it for service location. This is how you get the proxy and all that into the created objects.
public class MyFactory : IFactory
{
private readonly ILifetimeScope _scope;
public MyFactory(ILifetimeScope scope)
{
this._scope = scope;
}
public IApple Create(string color)
{
IApple fruit;
switch (color)
{
case "green":
fruit = this._scope.Resolve<GreenApple>();
break;
case "red":
fruit = this._scope.Resolve<RedApple>();
}
return fruit;
}
}
You'll need to register the factory and the things that the factory needs to resolve.
builder.RegisterType<MyFactory>().As<IFactory>();
builder.RegisterType<RedApple>();
builder.RegisterType<GreenApple>();
Finally, whenever you need something that uses the factory, that thing needs to be resolved. In this example, you can't really ever just new UsesTheFactory() - you have to resolve it (or have it injected into something else).
var builder = new ContainerBuilder();
builder.RegisterType<UsesTheFactory>();
builder.RegisterType<MyFactory>().As<IFactory>();
builder.RegisterType<RedApple>();
builder.RegisterType<GreenApple>();
var container = builder.Build();
using var scope = container.BeginLifetimeScope();
var user = scope.Resolve<UsesTheFactory>();
user.DoSomethingThatCallsTheFactory();
The key principle is that if you need that proxy injected anywhere in the pipeline, you can't use new. Full stop. If you need that thing, it needs to flow through Autofac somehow.
I am using Ninject version 3 in an MVVM-type scenario in a .NET WPF application. In a particular instance I am using a class to act as coordinator between the view and its view model, meaning the coordinator class is created first and the view and view model (along with other needed services) are injected into it.
I have bindings for the services, but I have not created explicit bindings for the view/view model classes, instead relying on Ninject's implicit self-binding since these are concrete types and not interfaces.
A conceptual version of this scenario in a console app is shown below:
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel();
kernel.Bind<IViewService>().To<ViewService>();
//kernel.Bind<View>().ToSelf();
//kernel.Bind<ViewModel>().ToSelf();
ViewCoordinator viewCoordinator = kernel.Get<ViewCoordinator>();
}
}
public class View
{
}
public class ViewModel
{
}
public interface IViewService
{
}
public class ViewService : IViewService
{
}
public class ViewCoordinator
{
public ViewCoordinator()
{
}
public ViewCoordinator(View view, ViewModel viewModel, IViewService viewService)
{
}
}
If you run this code as-is, the kernel.Get<> call will instantiate the ViewCoordinator class using the parameterless constructor instead of the one with the dependencies. However, if you remove the parameterless constructor, Ninject will successfully instantiate the class with the other constructor. This is surprising since Ninject will typically use the constructor with the most arguments that it can satisfy.
Clearly it can satisfy them all thanks to implicit self-binding. But if it doesn't have an explicit binding for one of the arguments it seems to first look for alternate constructors it can use before checking to see if it can use implicit self-binding. If you uncomment the explicit Bind<>().ToSelf() lines, the ViewController class will instantiate correctly even if the parameterless constructor is present.
I don't really want to have to add explicit self-bindings for all the views and view models that may need this (even though I know that burden can be lessened by using convention-based registration). Is this behavior by design? Is there any way to tell Ninject to check for implicit self-binding before checking for other usable constructors?
UPDATE
Based on cvbarros' answer I was able to get this to work by doing my own implementation of IConstructorScorer. Here's the changes I made to the existing code to get it to work:
using Ninject.Selection.Heuristics;
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel();
kernel.Components.RemoveAll<IConstructorScorer>();
kernel.Components.Add<IConstructorScorer, MyConstructorScorer>();
kernel.Bind<IViewService>().To<ViewService>();
ViewCoordinator viewCoordinator = kernel.Get<ViewCoordinator>();
}
}
using System.Collections;
using System.Linq;
using Ninject.Activation;
using Ninject.Planning.Targets;
using Ninject.Selection.Heuristics;
public class MyConstructorScorer : StandardConstructorScorer
{
protected override bool BindingExists(IContext context, ITarget target)
{
bool bindingExists = base.BindingExists(context, target);
if (!(bindingExists))
{
Type targetType = this.GetTargetType(target);
bindingExists = (
!targetType.IsInterface
&& !targetType.IsAbstract
&& !targetType.IsValueType
&& targetType != typeof(string)
&& !targetType.ContainsGenericParameters
);
}
return bindingExists;
}
private Type GetTargetType(ITarget target)
{
var targetType = target.Type;
if (targetType.IsArray)
{
targetType = targetType.GetElementType();
}
if (targetType.IsGenericType && targetType.GetInterfaces().Any(type => type == typeof(IEnumerable)))
{
targetType = targetType.GetGenericArguments()[0];
}
return targetType;
}
}
The new scorer just sees if a BindingExists call failed by overriding the BindingExists method and if so it checks to see if the type is implicitly self-bindable. If it is, it returns true which indicates to Ninject that there is a valid binding for that type.
The code making this check is copied from the SelfBindingResolver class in the Ninject source code. The GetTargetType code had to be copied from the StandardConstructorScorer since it's declared there as private instead of protected.
My application is now working correctly and so far I haven't seen any negative side effects from making this change. Although if anyone knows of any problems this could cause I would welcome further input.
By default, Ninject will use the constructor with most bindings available if and only if those bindings are defined (in your case they are implicit). Self-bindable types do not weight when selecting which constructor to use.
You can mark which constructor you want to use by applying the [Inject] attribute to it, this will ensure that constructor is selected.
If you don't want that, you can examine StandardConstructorScorer to see if that will fit your needs. If not, you can replace the IConstructorScorer component of the Kernel with your own implementation.
We have an MVC3 controller in which there is some 'common' work that we rolled into the controller constructor. Some of that common work is done by a losely coupled class (say ourService) that's dynamically resolved through Unity (for IoC / Dependency injection). ourService is null (i.e. not resolved) in the Controller's constructor BUT it's properly resolved in the usual Controller methods. The simple demo code below shows the issue:
public class Testing123Controller : BaseController
{
[Dependency]
public IOurService ourService { get; set; }
public Testing123Controller()
{
ourService.SomeWork(1); // ourService=null here !!
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // resolved properly here here !!
...
}
...
}
Question:
Why is there this different in Unity resolution behavior? I would expect consistent behavior.
How can I fix it so Unity resolves this even in the controller's contructor?
The way we've setup Unity 2.0 is :
Global.asax
Application_Start()
{
...
Container = new UnityContainer();
UnityBootstrapper.ConfigureContainer(Container);
DependencyResolver.SetResolver(new UnityDependencyResolver(Container));
...
}
public static void ConfigureContainer(UnityContainer container)
{
...
container.RegisterType<IOurService, OurService>();
...
}
IOurService.cs
public interface IOurService
{
bool SomeWork(int anInt);
}
OurService.cs
public class OurService: IOurService
{
public bool SomeWork(int anInt)
{
return ++anInt; //Whew! Time for a break ...
}
}
As a basic principle of classes, before an instance property can be set, the instance has to be instantiated.
Unity needs to set the dependency property, but it can't do so until the instance has been fully instantiated - i.e. the constructor must have completed executing.
If you are referencing the dependency property in the constructor, then this is too early - there is no way for Unity to have set it yet - and therefore it will be unset (i.e. null).
If you need to use the dependency in the constructor, then you must use constructor injection. Although in general, using constructor injection is usually the better method anyway:
public class Testing123Controller : BaseController
{
public IOurService ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
this.ourService = ourService;
this.ourService.SomeWork(1); // ourService no longer null here
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // also resolved properly here
...
}
...
}
Note: In the example I left ourService as a publicly gettable & settable property in case other parts of your code need to access it. If on the other hand it is only accessed within the class (and had only been made public for Unity purposes), then with the introduction of constructor injection, it would be best to make it a private readonly field.
You are using property injection (by using the Dependency attribute) rather than constructor injection so the dependency is not resolved until after the controller is instantiated. If you want to have access to the dependency is the constructor, just add it to the ctor:
private readonly IOurService _ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
_ourService = ourService;
_ourService.SomeWork(1); // ourService=null here !!
...
}
I'm afraid that for Unity to work on the constructor, the instance itself must be resolved using Unity. The fact that the Service property is null in the constructor supports this idea. If you call the Controller yourself (NOT with Unity), Unity has no time to resolve the property.
I have a structuremap configuration that has me scratching my head. I have a concrete class that requires a interfaced ui element which requires an interfaced validation class. I want the outer concrete class to get the default ui element, but get a concrete-class-specific validation object. Something like this:
class MyView
{
IPrompt prompt
}
class GenericPrompt : IPrompt
{
IValidator validator
}
class MyValidator : IValidator
{
bool Validate() {}
}
How can I configure structuremap with the Registry DSL to only use MyValidator when creating dependencies for MyView. (And assumedly using BobsValidator when creating dependencies for BobsView)
Are you getting MyView (and BobsView) from the container? Can we assume that they will all take an instance of IPrompt?
One approach would be to register all of your validators with a name that matches the names of your view. You could implement your own type scanner that just removes the Validator suffix:
public class ValidatorScanner : ITypeScanner
{
public void Process(Type type, PluginGraph graph)
{
if (!typeof (IValidator).IsAssignableFrom(type)) return;
var validatorName = type.Name.Replace("Validator", "");
graph.AddType(typeof(IValidator), type, validatorName);
}
}
Now, if you assume an IPrompt will always be requested by a View that follows that naming convention, your registry could look like:
public class ValidatorRegistry : Registry
{
public ValidatorRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.With<ValidatorScanner>();
});
ForRequestedType<IPrompt>().TheDefault.Is.ConstructedBy(ctx =>
{
var viewName = ctx.Root.RequestedType.Name.Replace("View", "");
ctx.RegisterDefault(typeof(IValidator), ctx.GetInstance<IValidator>(viewName));
return ctx.GetInstance<GenericPrompt>();
});
}
}
To retrieve your view with the appropriate validator, you would have to request the concrete type:
var view = container.GetInstance<MyView>();
Note that this will only work if you are retrieving your view with a direct call to the container (service location), since it depends on the "Root.RequestedType". Depending on how you plan to get your views, you might be able to walk up the BuildStack looking for a View (instead of assuming it is always Root).
I am trying to configure the NCommon NHRepository in my project with Structure Map. How do I stop it from choosing the greediest constructor?
public class NHRepository<TEntity> : RepositoryBase<TEntity>
{
public NHRepository () {}
public NHRepository(ISession session)
{
_privateSession = session;
}
...
}
My structure map configuration
ForRequestedType(typeof (IRepository<>))
.TheDefaultIsConcreteType(typeof(NHRepository<>))
Cheers
Jake
You can set the [DefaultConstructor] Attribute for the constructor you wish as a default. In your case, setting it on the NHRepository() constructor would make it the default constuctor for StructureMap to initialize.
Update: well, in the latest version of StructureMap, using .NET 3.5 you can also specify it using the SelectConstructor method:
var container = new Container(x =>
{
x.SelectConstructor<NHRepository>(()=>new NHRepository());
});
Finally, I'm sure you would be able to define it in the XML configuration of StructureMap, but I haven't used that. You could do a little search on it. For more information on the above method, see: http://structuremap.sourceforge.net/ConstructorAndSetterInjection.htm#section3
So +1 for Razzie because this would work if the NHRepository was in my own assembly, instead I choose to wrap the NHRepository with my own Repository like below..
public class Repository<T> : NHRepository<T>
{
[DefaultConstructor]
public Repository()
{
}
public Repository(ISession session)
{
}
}
ForRequestedType(typeof (IRepository<>))
.TheDefaultIsConcreteType(typeof (Repository<>));