my scenario looks (to me) very straight forward, but I couldn't find a resolution.
I have this scenario
public class Class<T> : IInterface where T : class
{
}
the interface cannot be made generic (coming from WCF lib.)
so I want to register the interface like this
container.RegisterType(typeof (IInterface ), typeof (Class<>));
and then resolve it with T
How can I do it? What am I missing?
my intention is doing something like
container.Resolve<IInterface>(/* specify T */);
If you don't need to resolve using the uncontrolled interface, you can make your own controlled interface which uses generics and derives from the uncontrolled interface. Then you can register the open generic and resolve the closed generic types.
public interface IControlled<T> : IUncontrolled {}
public class Controlled<T> : IControlled<T> {}
container.RegisterType(typeof(IControlled<>), typeof(Controlled<>));
IUncontrolled instance = container.Resolve<IControlled<string>>();
What am I missing?
You are missing a factory.
Think about it, there are no magic leprechauns working on the background guessing the type you need. You need to supply it. Either by explicitly stating what T
is while configuring like this:
container.RegisterType(
typeof(IInterface),
typeof(Class<SomeType>));
Or by creating a factory where you pass on the T
at runtime:
public interface IInterfaceFactory
{
IInterface Create<T>();
}
The factory can be registered as follows:
container.RegisterInstance<IInterfaceFactory>(
new InterfaceFactory(container));
And an implementation can look as follows:
public class InterfaceFactory : IInterfaceFactory
{
private readonly IUnityContainer container;
public InterfaceFactory(IUnityContainer container)
{
this.container = container;
}
public IInterface Create<T>()
{
return this.container.Resolve<Class<T>>();
}
}
Now you can inject the IInterfaceFactory
into consumers that need to work with IInterface
and they can request the version they need by calling the Create<T>()
method.
UPDATE
If you think this is too much code, you can also register a factory delegate as follows:
container.RegisterInstance<Func<Type, IInterface>>(
type => container.Resolve(
typeof(Class<>).MakeGenericType(type)));
This is basically the same, but now inlined in a delegate. Your consumers can now depend on a Func<Type, IInterface>
instead of a IInterfaceFactory
and pass a type instance on to the delegate.
I personally prefer the use of a descriptive interface such as IInterfaceFactory
. It's up to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With