What is the proper way to inject (via constructor) different types that implement that same interface? - unity-container

For example, let's say I have an interface 'IFeed' and two concrete types ('Feed1' and 'Feed2') that implement this interface. Now let's say I have a 'FeedManager' type that takes multiple parameters that will get resolved dynamically, two of which are of type 'IFeed' and I'd like both concrete type to be injected via constructor injection, not via manual resolve (I only use resolve once at the composition root). I have a feeling that I should be using a factory but I wanted to see what the proper way of doing this might be. Many thanks in advance.

If you want ALL implementations of IFeed, you can use array syntax in your constructor and then nothing special is needed at type registration time.
container.RegisterType<IFeedManager, FeedManager>();
container.RegisterType<IFeed, FeedA>("FeedA"); // The name doesn't matter
container.RegisterType<IFeed, FeedB>("FeedB"); // The name doesn't matter
Then the manager constructor...
public FeedManager(IFeed[] feeds) {...}
or if you want to add a little flare for calling the constructor directly...
public FeedManager(params IFeed[] feeds) {...}

Assuming you want to determine the actual concrete instances at runtime, you need to use named type registrations and then tell unity which one you want. So, use a factory method to construct the types required and pass those in as parameter overrides. Unity will use the overrides and resolve any remaining dependencies.
// register the types using named registrations
container.RegisterType<IFeedManager,FeedManager>()
container.RegisterType<IFeed, Feed1>("Feed1")
container.RegisterType<IFeed, Feed2>("Feed2")
Assuming your feed manager has the following named constructor parameters
class FeedManager : IFeedManager
{
public FeedManager (IFeed Feed1, IFeed Feed2, string someOtherDependency)
{
}
}
and create your feed manager:
static IFeedManager CreateFeedManager()
{
ParameterOverride feed1 = new ParameterOverride("Feed1"
,_container.Resolve<IFeed>("feed1"));
ParameterOverride feed2 = new DependencyOverride("Feed2"
,_container.Resolve<IFeed>("feed2"));
IFeedManager = _container.Resolve<IFeedManager>(feed1,feed2)
return IFeedManager;
}
Obviously this is overly simplified, but you you insert your own logic to determine which instance is to be resolved and then injected for each of the IFeed instances required by the FeedManager.

With Unity you would do this like so:
container.RegisterType<IFeed, Feed1>("Feed1");
container.RegisterType<IFeed, Feed2>("Feed2");
container.RegisterType<FeedManager>(new InjectionConstructor(new ResolvedParameter<IFeed>("Feed1"),
new ResolvedParameter<IFeed>("Feed2")));
This has now configured Unity so that when it needs to resolve a FeedManager, it will resolve Feed1 for the first parameter and Feed2 for the second parameter.

Related

SimpleIoc (mvvmlight) - how to automatically register all classes implementing a particular interface

Using SimpleIoc I want to automatically register all classes that implement a particular interface. I couldn't see a method on SimpleIoc's container to do this automatically so I put a some code together to iterate through the types to be registered. Unfortunately the code's not happy (see the commented line).
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(typeof(IFoo).IsAssignableFrom);
foreach (var type in types.Where(x=>x.IsClass))
{
container.Register<IFoo, type>(); //this line won't compile as type can't be resolved by the compiler
}
I realise there are less elegant ways of registering classes (such as just hard coding "container.Register" to register each class to the interface) but I'd like to be able to add new implementations without having to keep updating the ioc installer code. It would also be useful, at some point, for me to be able to register classes in other assemblies using the same method.
Any idea what I have to change to make this build (or is there a simpler/more elegant way to do this)?
UPDATE fex posted this comment:
"you can always iterate over types (like you do in your question) and create it with reflection (in your factory class) - (IFoo)Activator.CreateInstance(type); - in fact that's how service locators / ioc containers do it internally (in simplify)."
I've now updated my code to the following which works, with one caveat (the implementations must have a parameterless constructor, and dependencies must therefore be satisfied by the factory that I'm then using to serve up instances implementing IFoo). I've included the factory registration too for info.
Updated code:
// Get the types that implement IFoo...
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(typeof(IFoo).IsAssignableFrom);
// Register these types and use reflection to instantiate each instance...
foreach (var type in types.Where(x=>x.IsClass))
{
var t = type;
container.Register(() => (IFoo)Activator.CreateInstance(t), t.ToString());
}
// Inject all registered instances of IFoo into IFooFactory when it's instantiated.
// Note that instances of IFoo must have their own dependencies satisfied via the
// factory at runtime before being served by the factory.
container.Register<IFooFactory>(
() => new FooFactory(container.GetAllInstances<IFoo>()));

Unity and constructors

Is it possible to make unity try all defined constructors starting with the one with most arguments down to the least specific one (the default constructor)?
Edit
What I mean:
foreach (var constructor in concrete.GetConstructorsOrderByParameterCount())
{
if(CanFulfilDependencies(constructor))
{
UseConstructor(constructor);
break;
}
}
I don't want Unity to only try the constructor with most parameters. I want it to continue trying until it finds a suitable constructor. If Unity doesn't provide this behavior by default, is it possible to create an extension or something to be able to do this?
Edit 2
I got a class with two constructors:
public class MyConcrete : ISomeInterface
{
public MyConcrete (IDepend1 dep, IDepend2 dep2)
{}
public MyConcrete(IDepend1 dep)
{}
}
The class exists in a library which is used by multiple projects. In this project I want to use second constructor. But Unity stops since it can't fulfill the dependencies by the first constructor. And I do not want to change the class since the first constructor is used by DI in other projects.
Hence the need for Unity to try resolving all constructors.
Unity will choose the constructor with the most parameters unless you explicitly tag a constructor with the [InjectionConstructor] attribute which would then define the constructor for Unity to use.
When you state a suitable constructor; that is somewhat contingent on the environment. If for instance you always want to guarantee that a certain constructor is used when making use of Unity use the attribute mentioned previously, otherwise explicitly call the constructor you want to use.
What would be the point of Unity "trying" all constructors? It's purpose is to provide an instance of a type in a decoupled manner. Why would it iterate through the constructors if any constructor will create an instance of the type?
EDIT:
You could allow the constructor with the most params to be used within the project that does not have a reference to that type within its container by making use of a child container. This will not force the use of the constructor with a single param but it will allow the constructor with 2 params to work across the projects now.
You could also switch to using the single constructor across the board and force the other interface in via another form of DI (Property Injection), not Constructor Injection...therefore the base is applicable across the projects which would make more sense.

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

How to use Ninject in constructor injection of a type in an external assembly

I am loading a type from an external assembly and want to create an instance of the type. However, this type/class is setup for constructor injection by objects currently being managed/bound by Ninject. How can I use Ninject to create an instance of this type and inject any constructor dependencies?
Below is how I get this type.
Assembly myAssembly = Assembly.LoadFrom("MyAssembly.dll");
Type type = myAssembly.GetType("IMyType");
Assuming you've created a Kernel, you should be able to create and have it resolved via:
kernel.Get(type)
.... then I read the question.... Assuming MyAssembly.dll has an implementation of IMyType, you need (in your main assembly) :-
kernel.Load( "MyAssembly.dll")
And in your dynamically loaded assembly:-
public class Module : StandardModule
{
public override void Load()
{
Bind<IMyType>().To<MyType>();
}
}
And dont forget to see if MEF is the answer here, as you dont want to go writing reams of explicit plugin management and/or detection logic if you can help it (but if you're just doing straightforward stuff and are only doing the Assembly.LoadFrom() for the purposes of asking the question, you're probably still in Ninject's sweet spot.
Ditto, if you actually need to resolve an interface via Assembly.GetType(), you probably should be using something like dynamic to do the late binding you'll probably have to do (and before you know it you should be using a dynamic language or hosting a scriopting language)

how can i use structure map asp.net 3.5

I am new to the structure map but i want to use it in my asp.net site for dependency injection
can any one suggest me simple example to use structure map for the dependency injection
you will need to do something like this:-
StructureMapConfiguration
.ForRequestedType<IResourceA>()
.TheDefaultIsConcreteType<ResourceB>()
.CacheBy(InstanceScope.Singleton);
This tells StructureMap to inject ResourceB when there is a request for ResourceA.
Structure Map
You can configure programatically or via configuration file.
Programatical example (there are other ways):
StructureMap.StructureMapConfiguration.ForRequestedType<ISomething>().TheDefaultIsConcreteType<ConcreteSomething>();
then you can get an instance of the configured type using this sort of code:
//The concrete type will be ConcreteSomething
ISomething instance = ObjectFactory.GetInstance<ISomething>();
You can do it in a config file:
<StructureMap MementoStyle="Attribute">
<DefaultInstance PluginType="Blah.ISomething, Blah.SomethingDLL" PluggedType="Blah.Concrete.ConcreteSomething,Blah.ConcreteDLL"/>
</StructureMap>
and in the main method or Global.asax you can set this config by saying:
StructureMap.ObjectFactory.Initialize(x => { x.PullConfigurationFromAppConfig = true; });
and use it the same way as above:
ISomething instance = ObjectFactory.GetInstance<ISomething>();
If the concrete class has a constructor that needs instances injected in it, and you have those configured, the concrete types will get injected by the framework.
There are ways of passing parameters to constructors, dealing with Gereric types, creating named instances that are configured with specific constructor/property values. I use this framework and like it very much.

Resources