In the process of decoupling some code and I extracted an interface for one of our classes, and mapped it using Unity like so
Container.RegisterType<IUserAuthorizationBC, UserAuthorizationBC>(
new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>());
As you can see the class is UserAuthorizationBC and the interface is of course IUserAuthorizationBC. Once i did this I began to get an error in a class that I thought would not have mattered. The ctor for the class that now gives an error is as follows
public RoleAuthorizationService(IDataContractFactory factory,
UserAuthorizationBC businessProcessor)
: base(factory, businessProcessor)
{
_authBC = businessProcessor;
}
As you can see I haven't refactored it yet, I haven't even touched it, it was set up to get a concrete instance of UserAuthorizationBC and whoever created it is also injecting an IDataContractFactory which I did find mapped in our code base as you can see in following code snippet.
Container.RegisterType<IDataContractFactory, DefaultDataContractFactory>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
I get an error from unity as follows
Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the
dependency failed, type =
"HumanArc.Compass.Shared.Interfaces.Service.IRoleAuthorizationService",
name = "(none)".
Exception occurred while: Calling constructor Microsoft.Practices.Unity.InterceptionExtension.PolicyInjectionBehavior(Microsoft.Practices.Unity.InterceptionExtension.CurrentInterceptionRequest
interceptionRequest,
Microsoft.Practices.Unity.InterceptionExtension.InjectionPolicy[]
policies, Microsoft.Practices.Unity.IUnityContainer container).
Exception is: ArgumentException - Type passed must be an interface.
Now if I go comment out my mapping for IUserAuthorizationBC it will work fine again. I have no idea why.
actually I don't know why it ever works because if you look at the DefaultDataContractFactory it uses all generics which I would assume would always fail to resolve as at the time the unity doesn't know the type of T - see the class below.
public class DefaultDataContractFactory : IDataContractFactory
{
public DefaultDataContractFactory();
public virtual T Create<T>();
public virtual object Create(Type type);
public virtual Example<T> CreateExample<T>();
protected Type CreateFactoryType(Type instanceType);
}
So to sum things up there are two questions.
How does it even work in the first place before I added an interface for the IUserAuthorizationBC class and then added the mapping for unity - I would think that the IDataContractFactory would always blow it up.
Since it does work if I comment out the container mapping for IUserAuthorizationBC why does it stop working when I uncomment it - I would have thought it wouldn't make a bit of difference as this particular class always has been injected with a concrete instance of the UserAuthorizationBC
I thought I understood dependency injection fairly well - especially with unity but I am clearly missing the boat here.
I was going to make this a comment, but it's too long. Maybe your Unity container is configured for convention-based registrations, so your explicit registration is confusing matters. The IDataContractFactory/DefaultDataContractFactory pair needs to be explicity registered because the names don't follow the prescribed convention.
See if you have something like this in your code:
// This will register all types with a ISample/Sample naming convention
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default);
Prerequisite
Take a look at Interception using Unity. It looks like you are using interception with policy injection. Two conditions need to be met in order for a method to be intercepted. The policy needs to match on the method / type. And the type needs to opt-in to interception in the Unity registration by selecting an interceptor (InterfaceInterceptor, VirtualMethodInterceptor, or TransparentProxyInterceptor).
Answers
Commenting out that registration effectively opted-out that type from using interception.
You opted-in to interception but you told Unity to use interface interception. You are not resolving an interface, so it doesn't know how to generate a proxy for interception.
Possible solutions
Leave the registration as-is with the InterfaceInterceptor and update all constructors to use your new interface instead of the concrete type.
Change your new IUserAuthorizationBC registration to use VirtualMethodInterceptor and update any methods you want to be able to be intercepted to be virtual.
Change your new IUserAuthorizationBC registration to not specify an interceptor to effectively opt-out of interception.
Related
I'm using ASP.NET Core and I'm attempting to create a resolvable class which has an optional parameter:
public class Foo
{
public Foo() : this(null)
{}
public Foo(IValidator<FooEntity> validator)
{
}
}
I've created two constructors for this object so that if a dependency isn't found, I would assume it would just fall back to the default constructor.
However when I run my application I receive this error
Additional information: Unable to resolve service for type 'FluentValidation.IValidator`1[FooEntity]' while attempting to activate 'Foo'
I know there is probably a way to manually resolve the construction of the Foo object. But I would prefer not to do that because I will have to do this for every class that I create without a validator.
Does anyone know how to configure ASP.NET Core DI to fall back to a different constructor if the dependency is not found?
EDIT
Sorry, I should of been a bit more clear before.
This Foo class I'm referring to in really a base class for a CRUD Service, which will be used over and over again.
I'm looking for a generic solution which doesn't require me to configure each Service I create each time.
So using a lambda to resolve this is not an option, The null object pattern seems feasible but I can't comprehend how to write a generic one in which I won't have to configure for each service
I think its general behavior of Containers to resolve the constructor with the most parameters.
Basically what AddTransient does is the following:
services.AddTransient<Foo>();
//equals to:
services.AddTransient<Foo>(c=> new Foo(c.GetService<IValidator<FooEntity>()));
So you can register it yourself like this:
services.AddTransient<Foo>(c=> new Foo());
At this point in the startup class you should know if IValidator<FooEntity> has been registered. Or, if you are using reflection add this logic to your reflection code.
Difference
The difference between the 2 options is that with the first option is that the lambda function to resolve the class is created on startup. + if you change the constructor no code needs to be changed elsewhere.
If you create the lambda yourself this lambda is compiled on build, so theoretically startup should be faster (I have not tested this).
Great mindset
A great mindset is to own the libraries you are using. In Visual studio/Resharper you can decompile source-code, or you can find the repositories on github nowadays.
There you can see the source code, you can see how the services parameters is 'compiled' to the IServiceProvider (see BuildServiceProvider() method, it will give you alot of insight.)
Also look at:
ServiceDescriptor, Your type registration.
Service, the one that resolves the type.
Solution
best way to do it is this, (sorry for psuedo code but i have no editor at hand).
getTypes()
.Where(x=> x.EndsWith("Entity") //lets get some types by logic
.Select(x=> typeof(IValidator<>).MakeGeneric(x)) //turn IValidator into IValidator<T>
.Where(x=> !services.IsRegistered(x))
.Each(x=> services.Add(x, c=> null)) //register value null for IValidator<T>
You need to register the IValidator<T> first:
var services = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
services.AddTransient<IValidator<FooEntity>, RealValidator<FooEntity>>();
services.AddTransient<Foo>();
var serviceProvider = services.BuildServiceProvider();
var validator = serviceProvider.GetService<IValidator<FooEntity>>();
var foo = serviceProvider.GetService<Foo>();
Assert.NotNull(validator);
Assert.NotNull(foo);
I'm using Unity's Register by convention mechanism in the following scenario:
public interface IInterface { }
public class Implementation : IInterface { }
Given Implementation class and its interface I'm running RegisterTypes in the following way:
unityContainer.RegisterTypes(
new[] { typeof(Implementation) },
WithMappings.FromAllInterfaces,
WithName.Default,
WithLifetime.ContainerControlled);
After this call, unitContainer contains three registrations:
IUnityContainer -> IUnityContainer (ok)
IInterface -> Implementation (ok)
Implementation -> Implementation (???)
When I change the call as follows:
unityContainer.RegisterTypes(
new[] { typeof(Implementation) },
WithMappings.FromAllInterfaces,
WithName.Default);
The container contains only two registrations:
IUnityContainer -> IUnityContainer (ok)
IInterface -> Implementation (ok)
(this is the desired behaviour).
After peeking into Unity's source code, I've noticed that there is some misunderstanding about how IUnityContainer.RegisterType should work.
The RegisterTypes method works as follows (the comments indicate what are the values in the scenarios presented above):
foreach (var type in types)
{
var fromTypes = getFromTypes(type); // { IInterface }
var name = getName(type); // null
var lifetimeManager = getLifetimeManager(type); // null or ContainerControlled
var injectionMembers = getInjectionMembers(type).ToArray(); // null
RegisterTypeMappings(container, overwriteExistingMappings, type, name, fromTypes, mappings);
if (lifetimeManager != null || injectionMembers.Length > 0)
{
container.RegisterType(type, name, lifetimeManager, injectionMembers); // !
}
}
Because fromTypes is not empty, the RegisterTypeMappings adds one type mapping: IInterface -> Implementation (correct).
Then, in case when lifetimeManager is not null, the code attempts to change the lifetime manager with the following call:
container.RegisterType(type, name, lifetimeManager, injectionMembers);
This function's name is completely misleading, because the documentation clearly states that:
RegisterType a LifetimeManager for the given type and name with the container. No type mapping is performed for this type.
Unfortunately, not only the name is misleading but the documentation is wrong. When debugging this code, I've noticed, that when there is no mapping from type (Implementation in the scenarios presented above), it is added (as type -> type) and that's why we end up with three registrations in the first scenario.
I've downloaded Unity's sources to fix the problem, but I've found the following unit test:
[TestMethod]
public void RegistersMappingAndImplementationTypeWithLifetimeAndMixedInjectionMembers()
{
var container = new UnityContainer();
container.RegisterTypes(new[] { typeof(MockLogger) }, getName: t => "name", getFromTypes: t => t.GetTypeInfo().ImplementedInterfaces, getLifetimeManager: t => new ContainerControlledLifetimeManager());
var registrations = container.Registrations.Where(r => r.MappedToType == typeof(MockLogger)).ToArray();
Assert.AreEqual(2, registrations.Length);
// ...
- which is almost exactly my case, and leads to my question:
Why is this expected? Is it a conceptual mistake, a unit test created to match existing behaviour but not necessarily correct, or am I missing something important?
I'm using Unity v4.0.30319.
We would need to reach out to the original developers to be sure, but this is what I can only assume as to why it was coded to be this way...
Unity has a feature that allows concrete classes to be resolved even though the type has not been registered. In this scenario, Unity must make the assumption that you want the default lifetime manager (transient) and no injection members for that concrete type. If you don't like those default policies, then you need to register the concrete type yourself and specify your customization.
So following that train of thought, when you call RegisterTypes and you do specify a lifetime manager and/or an injection member, then Unity makes the assumption that you want that behavior when resolving by the interface and by the concrete type. But if you do not specify those policies, then Unity doesn't need the concrete registration because it will fall back to the default behavior when resolving the concrete type.
The only other explanation that I can come up with is for the sake of plugins. InjectionMember is extensible, so Unity thinks you could be passing in a custom behavior for a plugin. And it therefore makes the assumption that you might want that custom behavior for the plugin to be applied to both the interface and the concrete when you are registering by convention.
I understand you are running into this issue while attempting to unit test your application bootstrap. I'm assuming you are testing to ensure the types you register and only those types are registered. This is breaking your tests because some tests find this extra concrete registration.
From a unit test perspective, I would argue that you are going beyond the scope of what you are attempting to test. If you start using plugins, there will be quite a few other registrations that start appearing (like interception policies and behaviors). That will just add to the problem you are seeing now because of the way you are testing. I would recommend you change your tests to ensure only a white-list of types are registered and ignore everything else. Having the concrete (or other additional registrations) is benign to your application.
(e.g. put your interfaces in the white-list and assert each one of those is registered and ignore the fact that the concrete is registered)
This behavior was fixed in version 5.2.1, as explained in this article:
Now all information passed to Unity during registration is stored with
FromType instead of ToType. So registering type like this:
container.RegisterType<ILogger, MockLogger>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
creates just one registration ILogger and associates LifetimeManager
and all provided InjectionMemebers with it. At this point MockLogger
is still unregistered.
One reason that I can think of for the current behavior is that it reuses the existing Unity functionality/implementation and makes the registration by convention feature fairly easy to implement.
The existing Unity implementation that I'm thinking of is the separation of type mapping and build plan into different policies so if you are working on Unity source code that would be a common way to think about things. Also, from what I've read in the past, the Registrations property seems like it was thought of as a second class citizen and not intended to be used for much more than debugging so having another registration might not have seemed to be a big deal. Perhaps those two points put together were part of the decision?
Besides the extra item in the Registrations collections the feature is working in this case.
Then, in case when lifetimeManager is not null, the code attempts to change the lifetime manager with the following call
The RegisterTypes method doesn't actually set a LifetimeManager. If no LifetimeManager is specified then the concrete target type is not explicitly registered and Unity relies on the internal default behavior when creating the object (in this case a default LifetimeManager of TransientLifetimeManager).
But if anything is specified that could potentially override the defaults (i.e. a LifetimeManager or InjectionMembers) then the concrete type will be explicitly registered.
It should be possible to get Registration by Convention to work without the extra registration. However, there are some complexities to consider. If a concrete type implements many interfaces there could be multiple mapping registrations for a concrete type but each registration will need it's own lifetime manager instance (they can't be reused). So you could create new lifetime manager instances for each mapping registration but (I believe) only the last lifetime manager would be used. So to avoid unnecessary object creation perhaps only assign the lifetime manager on the last type mapping? That's just one scenario that occurred to me -- there are a variety of scenarios and combinations to consider.
So I think the current implementation is an easy way to implement the feature without having to specifically handle any edge cases with the only side effect being the extra registration. I would guess that was probably part of the thinking at the time (but I wasn't there so it's just a guess).
I am trying to migrate from Unity to Simple Injector in my new project. It is so much faster than Unity that I have to give it a shot. I have had a few bumps, but nothing I could not work around. But I have hit another one with "Look-up by Key"
I have read this where the creater of simple injector states his belief that you should not need to resolve more than one class per interface.
I must be a poor programmer, because I have done that with Unity (which supports it very well) and want to do it in my current project.
My scenario is that I have an IRepository interface. I have two separate repositories I want to abstract using the IRepository interface. Like this:
container.Register<FirstData>(() => new FirstData());
container.Register<IRepository>(
() => new GenericRepository(container.GetInstance<FirstData>()));
container.Register<SecondEntities>(() => new SecondEntities());
container.Register<IRepository>(
() => new GenericRepository(container.GetInstance<SecondData>()));
IRepository/GenericRepository is a fairly common abstraction, but you can only have one in SimpleInjector
In Unity I could register both of my repositories and then setup my constructor injection to inject the instance that I needed. This was accomplished using a key for the instance. (I did not need to do a Resolve call in my normal code nor add a dependency to Unity outside my setup.)
With simple injector this does not work. But, for better or worse, the owner of Simple Injector thinks this feature is a bad idea.
NOTE: The author's "in app" system looks like it uses a string key for look-up, but it still requires a different class each time (DefaultRequestHandler, OrdersRequestHandler and CustomersRequestHandler). I just have a GenericRepostory which allows me to abstract my repository methods regardless of what I am connected to.
I suppose I could inherit my GenericRepostory for each time I want to instantiate it. Or have it take a random type parameter that I don't need. But that muddles my design, so I am hoping for another way to do it.
So are there any work arounds that don't have me creating bogus types to differentiate between my two IRepository/GenericRepository instances?
We ended up changing our Generic Repository to look like this:
/// The Type parameter has no funcionality within the repository,
/// it is only there to help us differentiate when registering
/// and resolving different repositories with Simple Injector.
public class GenericRepository<TDummyTypeForSimpleInjector> : IRepository
(We added a type parameter to it).
We then created two dummy classes like this (I changed the names of the classes to match my example):
// These are just dummy classes that are used to help
// register and resolve GenericRepositories with Simple Injector.
public class FirstDataSelector { }
public class SecondDataSelector { }
Then I can register them like this:
container.Register<FirstData>(() => new FirstData());
container.Register(() => new GenericRepository<FirstDataSelector>
(container.GetInstance<FirstData>()));
container.Register<SecondEntities>(() => new SecondEntities());
container.Register(() => new GenericRepository<SecondDataSelector>
(container.GetInstance<SecondData>()));
(Note the generic type param on the GenericRepository and that I do not register it as an IRepository. Those two changes are essential to making this work.)
This works fine. And I am then able to use that registration in the constructor injection of my business logic.
container.Register<IFirstBusiness>(() => new FirstBusiness
(container.GetInstance<GenericRepository<FirstDataSelector>>()));
container.Register<ISecondBusiness>(() => new SecondBusiness
(container.GetInstance<GenericRepository<SecondDataSelector>>()));
Since my Business classes take an IRepository it works fine and does not expose the IOC container or the implementation of my repository to the business classes.
I am basically using the Type parameter as Key for lookup. (A hack I know, but I have limited choices.)
It is kind of disappointing to have to add dummy classes to my design, but our team decided that the drawback was worth it rather than abandoning Simple Injector and going back to Unity.
Your own answer is actually quite good, but its unfortunate that you see the generic type parameter as a dummy; you should make it first class citizen of your design:
public interface IRepository<TData> { }
public clss GenericRepository<TData> : IRepository<TData>
{
public GenericRepository(TData data) { }
}
This way you can simply register them as follows:
container.Register<IRepository<FirstData>, GenericRepository<FirstData>>();
container.Register<IRepository<SecondData>, GenericRepository<SecondData>>();
Your business classes can in that case simply depend on the generic IRepository<FirstData> and IRepository<SecondData> and can simply be registered as follows:
container.Register<IFirstBusiness, FirstBusiness>();
container.Register<ISecondBusiness, SecondBusiness>();
Note how the registrations given here don't use any lambdas. Simple Injector can find this out for you. This makes your DI configuration much simpler, more readable, and especially: more maintainable.
This way you make your design very explicit and unambiguous. Your design was ambiguous because you had a single (non-generic) IRepository interface that should be mapped to several implementations. Although this doesn't have to be bad in all cases, in most cases this ambiguity can and should be prevented, because this complicates your code and your configuration.
Further more, since your generic GenericRepository<T> now maps to the generic IRepository<T> we can replace all Register<IRepository<T>, GenericRepository<T>>() registrations with a single line:
// using SimpleInjector.Extensions;
container.RegisterOpenGeneric(typeof(IRepository<>),
typeof(GenericRepository<>);
To take it even one step further, your business classes could perhaps as well benefit from generic typing. Take a look at this article for instance where each business operation gets its own class but all business operations are hidden behind the same generic ICommandHandler<TCommand> abstraction. When you do this, all business classes can be registered with a single call:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
typeof(ICommandHandler<>).Assembly);
This call searches the supplied assembly for implementations of the ICommandHandler<TCommand> interface and registers each found implementation in the container. You can add new pieces of business logic (use cases) without having to change the configuration. But this is just one of the many advantages of having such abstraction over your business logic. An other great advantage is that it makes adding cross-cutting concerns (such as logging, transaction handling, security, audit trail, caching, you name it) much easier to implement.
Having used Windsor for quite some time, I'm a little surprised that I haven't come across this "design" issue sooner. I don't know how best to tackle it.
I have a class ConverterService that is used to perform data conversions. This is the interface (I've changed the parameters/return values to objects to simplify the sample):-
public interface IConverterService
{
object ConvertData(object sourceData);
}
The converter class needs some configuration settings, provided by an ISettingsProvider. The settings are used both in the constructor and the ConvertData() method. I therefore inject the ISettingsProvider into the constructor:-
public class ConverterService : IConverterService
{
private ISettingsProvider _settingsProvider;
public ConverterService(ISettingsProvider settingsProvider)
{
_settingsProvider = settingsProvider;
// Do some one-time initialisation using info from settingsProvider
// and store the results in class variables (not shown), used by ConvertData.
}
public object ConvertData(object sourceData)
{
// Do the conversion - also uses _settingsProvider,
// and other variables initialised in the constructor ..
}
}
Both the ConverterService and SettingsProvider are registered with Windsor in the usual way:-
container.Register(Component.For<IConverterService>().ImplementedBy<ConverterService>().LifeStyle.Singleton);
container.Register(Component.For<ISettingsProvider>().ImplementedBy<SettingsProvider>().LifeStyle.Singleton);
Any class that needs to use the converter gets an IConverterService injected via its constructor - standard stuff. This works fine, but I now need the ability for many different consumers to use the ConverterService with different settings providers (two or three at most).
I can't make ConverterService transient as I don't want the initialisation overhead each time. It feels like I need a separate instance of the ConverterService for each type of ISettingProvider, but I'm not sure if/how I can accomplish this using Windsor, or is a more fundamental refactoring needed?
And how would I register the different settings providers, all of which implement ISettingsProvider? More specifically how would Windsor resolve the correct one (bearing in mind that the ConverterService constructor is merely expecting an ISettingsProvider)?
Any suggestions as to how I should (re-)design the classes would be much appreciated.
Can you not use a naming convention for your instances and control them that way? So each instance of your IConverterService would have an associated name to indicate which configuration it was using.
This question features some information on using named components/instances.
Castle Windsor - How to map Named instance in constructor injection
I have read some posts on here about not mixing parameters when passing into a constructor, but have a question. I have classes and they all depend on a company parameter, all of the methods are dependent on the company. I do not want to have to pass the company in on every method call, I would like to pass that into the constructor. This does make it difficult on the classes because I have to pretty much make sure the constructors of the concrete classes take in certain parameteres, which I am not a fan of (cannot put that in the contract that is the interface). Recommend just passing the company into every method call in the class???
If all the methods require a company name then it is perfectly reasonable from a OOP design point of view to pass this company name into the constructor of your class. This means that your class cannot function correctly without a company name so any consumer of the class will be forced to supply required dependency.
Assuming you aren't working with a known IoC framework which already handles this for you, you could always implement this as property injection. Not that I see a problem with doing this at the constructor level either - you haven't really said why you feel that's a problem.
Certainly wouldn't recommend passing it to every method (clearly redundant).
If the behaviour of your class depends on said company name, what is wrong with passing it in with the constructor? A constructor is a contract all by itself - you will have to instantiate it with something.
Aye, in the IoC world, most tools (Spring.Net, Castle Windsor, even LinFu) have methods that can take care of that for you so you define it one in a config and every time you get a copy (from the container or whatever) it comes preconfigured.
You can wrap your 'container'
IWindsorContainer _ConfiguredContainer = null;
public IWindsorContainer GetContainer()
{
if (LoggedIn == false)
throw new InvalidOperationException("Cannot be called before a user logs in");
if (_ConfiguredContainer == null)
{
_ConfiguredContainer = new WindsorContainer(new XmlInterpreter());
// Do your 'extra' config here.
_ConfiguredContainer.AddComponentWithProperties(/*blah blah blah*/);
}
return _ConfiguredContainer;
}
You could have an ICommonSettings (almost like a global static class) that gets injected into your login manager (to set the comany name) and into the object your talking about. Then your free from having to pass it to the constructor or the method.