Constructor resolve collection of generic interfaces using Autofac - c#

I've got a lot of implementations of a specific generic interface and would like to resolve all of these implementations in the constructor. Of course, I can just add every implementation in the constructor. This will cause the constructor to have over 30 parameters, which isn't very nice to look and develop at.
While doing some research on the matter I discovered it's possible to inject an IEnumerable of an interface in the constructor, somewhat like this IEnumerable<IScriptExecution> scriptExecutionImplementations
This is what I'm searching for, but I need it to be like so:
public TheConstructor(IEnumerable<IScriptExecution<T>> scriptExecutionImplementations)
{}
Is it possible to inject all the IScriptExecution<T> in the constructor, using Autofac?
The following is an excerpt from my registration class:
builder.RegisterType<Library.ShardManager.Execution.DataScript.Users>().As<IScriptExecution<DBUser>>();
builder.RegisterType<Library.ShardManager.Execution.DataScript.Companies>().As<IScriptExecution<DBCompany>>();
Note: I don't think I need to use the Open Generics, because I already know the types and you can't use open generics in a constructor.
As requested by Jim Bolla in the comment section, an example on how I want to use this.
At the moment I've got this constructor:
public MoveShardletData(Guid shardletId, ShardLocation oldLocation, ShardLocation newLocation, ILog log,
IScriptCreator<DBAnalyticsInvitation> scriptAnalyticsInvitation, IScriptCreator<DBAnalyticsPromotion> scriptAnalyticsPromotion,
IScriptCreator<DBAnalyticsRetailerSubscriptionModule> scriptAnalyticsRetailerSubscriptionModule, IScriptCreator<DBAnalyticsRetailerSubscription> scriptAnalyticsRetailerSubscription, //and the list goes on...
The piece of code where I want to use the IScriptCreator<T> objects looks a bit like this:
var analyticsInvitations = GetTheAnalyticsInvitationObjects(someLocalVariableInTheCurrentScope)
var script = scriptAnalyticsInvitation.Insert(analyticsInvitations);
sb.Append(script);
//With all IScriptCreator<T> objects listed here in the same fashion.
It would be nice if this could be done in a loop. Because of the someLocalVariableInTheCurrentScope it's a bit hard to extract this piece of code.
The collection analyticsInvitations is the type T. If I can access the Autofac container I can probably resolve the correct IScriptCreator<T> manually, but that's cheating thus not advised.

Related

Get an object from the Unity container where the interface is InterfaceA<InterfaceB> where InterfaceB is variable

I'm trying to make some C# code less verbose but I've run into a problem with using Unity to retrieve objects based on an interface like this:
public interface IMessagesHandler<T>
Leading to several classes implementing this interface defined as followed:
public class AmendDataTypeHandler : IMessageHandler<IAmendDataType>
So yes, IAmendDataType is an interface.
Hence, when I use the Unity Container it is in this form:
var amendDataTypeHandler = IoC.Container.Resolve<IMessageHandler<IAmendDataType>>();
The problem is I have multiple similar classes for each 'DataType'. I have that DataType as a variable of type Type. What I can't see is how to retrieve the appropriate IMessageHandler implementation.
For a conventional interface that doesn't act on Type T I could just use:
var conventionalImplementation = IoC.Container.Resolve(type_variable_containing_the_interface);
But I cannot see a way to adapt this for my situation nor can I find examples online (partly maybe because I cannot work out how to describe InterfaceA<T> in google to find them)
In the meantime, I have a large switch statement based on the type being passed in which is just very ugly and hard to maintain code.
Any help greatly appreciated.
Thanks

In ReactiveUI, how to call GetService for MutableDependencyResolver

I am reading the book You, I and ReactiveUI and my question relates to the source code for the book at https://github.com/kentcb/YouIandReactiveUI. The versions of ReactiveUI and Splat have changed since the code was published and one portion of the code cannot be duplicated in the current versions. I have contacted the author and am still waiting on a response as of this time of posting this question, and so I am submitting this question here.
In App.xaml.cs there is a call to a Registrations.cs class that passes the current mutable dependency resolver:
public App()
{
this.autoSuspendHelper = new AutoSuspendHelper(this);
Registrations.Register(Splat.Locator.CurrentMutable);
}
In the Registrations.cs class, there is a line that takes that IMutableDependencyResolver and calls GetService:
public static void Register(IMutableDependencyResolver container)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
}
I, too, would like to get the IVewLocator service, but IMutableDependencyResolver no longer has a GetService method.
So my question is, how should this code be modified to have the same functionality?
The Splat.Locator.Current is an IReadonlyDependenyResolver and that does have a GetService method. Should that be used instead? I wasn't sure if I should change to using Splat.Locator.Current in case there was a reason that Splat.Locator.CurrentMutable was used and wanted to make sure that if I changed to using Splat.Locator.Current that it would not introduce anything unexpected.
UPDATE:
Just want to add that, armed with the knowledge from DPVreony's answer that it is typically the same class implementing the two interfaces, I was able to implement some later lines in the Registrations.cs class that I needed.
So, further in that class, there are some lines that register constants. These needed the mutable dependency resolver. So you can just pass both the read only and mutable into the Registrations class and use them where needed, as shown below:
public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));
...
var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
...
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}
And then call the method like so:
Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);
There was a change in Splat due to how some DI containers behave with registering services (i.e. they keep re-initializing). So get functionality was split off onto the IReadonlyDependenyResolver exposed by Splat.Locator.Current
It was to encourage the mindset of use the MutableLocator to get everything in place and then after that you should only ever need to read using Splat.Locator.Current so you're fine to use it. Typically it's the same class implementing the 2 interfaces, so it's a semantic change to reduce risks of tearing down the locator by mistake.
So in short yes Splat.Locator.Current is for GetService
Hope that all makes sense.

Parameterize object with enum

I'm using C# and Unity Dependency Injection for developing a MVVM application in WPF. I'm looking for a cleanest solution for a following problem.
Some of my classes are parametrized with enums, for example, I have a class AudioChannelViewModel (let's call it for short A) and I want to register two instances of the class, one for Channel.Left and one for Channel.Right. This alone is not a problem, because I register those instances by naming them in RegisterType and then referring to them later by [Dependency(name)] attribute.
Moreover, A depends on some other classes, lets call them Dep1, Dep2 and Dep3. To perform the initialization of A, I must have ALL of my dependencies and the information about the Channel.
I tried to use the following strategies:
Property injection of Dep1, Dep2 and Dep3 and setting A's Channel in constructor by RegisterType with InjectionConstructor parameter. But how should I know when A is ready to be initialized? AFAIK I cannot assume anything about the property injection order.
Constructor injection of all four items. It would be IMHO the cleanest solution, as I would be able to perform initialization in constructor. But I'm unable to get this working in Unity. Registering A with InjectionConstructor param for Channel throws an exception, and registering with four InjectionConstructor params seems ugly.
Constructor injection of Dep1, Dep2 and Dep3 and property injection of Channel. Then I can initialize my class in the Channel setter. It works for this case, but what if A would be parametrized by more than one property? Then I wouldn't know when A is fully built up and ready for initialization.
How should the initialization be performed? Or maybe I'm making things overly complicated.
You don't say exactly what the exception was that you observed in strategy #2, but this is the approach I would be using (given your other requirements for being able to other initialisation having had all the dependencies successfully resolved). I suspect the problem is that you aren't providing a 'value' for all of the arguments of the constructor... InjectionConstructor assumes the constructor you want is the one matching the types of the values provided to the InjectionConstructor.
E.g. if you want to register a constructor for such a class...
public class AudioChannelViewModel {
public AudioChannelViewModel(Channel channel, Dep1 dep1, Dep2 dep2, Dep3 dep3) {
...
}
}
You should register it thus...
container.RegisterType<AudioChannelViewModel>("left",
new InjectionConstructor(Channel.Left,
typeof(Dep1), typeof(Dep2), typeof(Dep3)));
container.RegisterType<AudioChannelViewModel>("right",
new InjectionConstructor(Channel.Right,
typeof(Dep1), typeof(Dep2), typeof(Dep3)));
Unity will use the provided value for the first argument (a Channel enum value) and will then resolve the Dep1, Dep2 and Dep3 instances. You can also use ResolvedParameter<T> as an argument to InjectionConstructor if there were specific named instances of Dep1, Dep2 or Dep3 that you require.
Just providing Channel.Left or Channel.Right alone is insufficient, as Unity will believe it is being asked to use a constructor with just a Channel argument.
Or; if you HAVE already tried that and it isn't working... maybe Unity doesn't support enums in this instance (pun intended).
This MSDN page might shine some more light on the issue.

firsts steps with an IoC because I hit a wall, please explain the 'behind the scenes'

So I started this new project, and I was trying to incorporate all the new design principles I was reading about, namely trying to make things loosely coupled, testable, and following some patterns.
So I then ran into the issue of having to pass too many factories/managers into my classes constructor, which led me into Dependancy injection.
public class SomeClass
{
public SomeClass(IDBFactory factory, IOrderManager orderManager, ....)
}
So if I use ninject, from what I understand, I would then bind a particular implementation to the class.
So what is going on behind the scenes?
NInject will, whenever I instantiate SomeClass, it will bind the implementation that I defined in the config file?
i.e.
I do:
ISomeClass sc = NInject.Get<ISomeClass>();
and ninject will do:
new SomeClassImpl(pass in all the implementaitons in the constructor)
correct?
I don't know NInject, but most DI Containers support Auto-Wiring, which works this way:
When you request ISomeClass, it looks through its list of all registered types. Using this list, it discovers that the desired implementation of ISomClass is SomeClass.
It will use SomeClass' constructor to create an instance (perhaps using Activator.CreateInstance), so it uses Reflection to figure out which paramters are required.
For each paramameter, it looks at the type and repeats step 1-2 for each.
Thus, the process may be recursive, but in the end, you should end up with a fully populated object graph where all dependencies are satisfied.

Is this a good factory method implementation?

I'm working on a module that requires a strictly decoupled interface. Specifically, after instantiating the root object (a datasource), the user's only supposed to interact with the object model via interfaces. I have actual factory objects (I'm calling them providers) to supply instances that implement these interfaces, but that left the clumsiness of getting the providers. To do so, I've supplied a couple methods on the datasource:
public class MyDataSource
{
private Dictionary<Type, Type> providerInterfaceMapping = new Dictionary<Type, Type>()
{
{ typeof(IFooProvider), typeof(FooProvider) },
{ typeof(IBarProvider), typeof(BarProvider) },
// And so forth
};
public TProviderInterface GetProvider<TProviderInterface>()
{
try
{
Type impl = providerInterfaceMapping[typeof(TProviderInterface)];
var inst = Activator.CreateInstance(impl);
return (TProviderInterface)inst;
}
catch(KeyNotFoundException ex)
{
throw new NotSupportedException("The requested interface could not be provided.", ex);
}
}
}
I've modified some details on the fly to simplify (e.g., this code snippet doesn't include the parameters passed to the implementation instance that's created). Is this a good general approach for implementation of a factory method in C#?
You should rather take a step back and ask whether using a factory method at all is a good idea? In my opinion, it is not.
There are more than one issue with factory methods, and your example illustrates several:
You need to have a hard reference to the implementation (FooProvider in addition to IFooProvider), which is exactly the situation you are trying to avoid in the first place. Even if the rest of your code only consumes IFooProvider, your library is still tightly coupled to FooProvider. Some other developer may come by and start using FooProvider directly if he/she isn't aware of your factory method.
You only support implementations that have default constructors, since you are using Activator.CreateInstance. This prevents you from using nested dependencies.
Instead of trying to manually control dependencies, I would recommend that you take a look at Dependency Injection (DI). Whenever your code needs an IFooProvider, supply it with Constructor Injection.
Don't reinvent your own implementation of dependency injection, use an existing library like Spring.NET or the Microsoft Unity application block.
Injecting dependencies is a common programming problem that you shouldn't have to solve yourself. There are some nice lightweight libraries out there (I mentioned a couple above) that do the job well. They support both declarative and imperative models of defining dependencies and are quite good at what they do.
Technically this is fine, however most times when I see a factory it usually returns the same type interface, for instance something like IProvider rather than IFooProvider or IBarProvider which to me doesn't make sense. If you are going to have FooProvider and BarProvider then why have different interfaces for them. I would use one interface IProvider and have FooProvider and BarProvider implement that.
Regardless of the rightness or wrongness of using the factory method (as that is not what you asked about!), your implementation looks fine to me.
Something that may work for you better than hardcoding the type mapping is putting that info in a configuration file and loading it in your app.
For what it is worth I use this pattern all the time and have abstracted some of this sort of logic into a reusable assembly. It uses reflection, generics and attributes to locate and bind the concrete types at runtime. http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx
This helps to address Mark's concern because implementation types are not hardcoded, and further the implementation types are determined by the installation, not in project assembly references.

Categories