Unity register generic type for non generic interface

冷暖自知 提交于 2019-12-01 06:48:01

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!