繁体   English   中英

Unity无法解析Generic存储库

[英]Unity can't resolve Generic repository

我看到了类似的其他问题,但它没有解决我的问题。 一个问题的示例: Unity注册非泛型接口的泛型类型

我有界面

    public interface IRepository<T>
    {
        T GetById(int id);
    }

和班级

    public class Repository<T> : IRepository<T>
    {
         public T GetById(int id)
         {
             Console.WriteLine("Type: " + GetType());
             return default(T);
         }
    }

我注册了

    Container.RegisterType(typeof(IRepository<>), typeof(Repository<>));

并尝试解决它

    IRepository<string> IRepository = Container.Resolve<IRepository<string>>();

它总是返回null。

我看到了许多不同的来源,他们都表现出相同的实现方式。 为什么不起作用?

UPDATE

这是实际的实现:

public class Program
{
    static Program()
    {
        DIDefaultRegisters.Initialize();
    }

    public static void Main(string[] args)
    {
        var iRepository = UnityDIFacade.Resolve<IRepository<string>>();

        iRepository.GetById(1);
    }
}

public class DIDefaultRegisters
{
    public static void Initialize()
    {
        Register(typeof(IRepository<>),typeof(Repository<>));
    }

    private static void Register(Type from, Type to)
    {
        UnityDIFacade.RegisterType(from, to);
    }
}

public class UnityDIFacade
{
    private static readonly IUnityContainer Container;

    static UnityDIFacade()
    {
        IUnityContainer container = new UnityContainer();

        var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        if (section != null)
            section.Configure(container);

        Container = container;
    }

    public static T Resolve<T>()
    {
        T resolved = default(T);

        if (Container.IsRegistered<T>()) 
            resolved = Container.Resolve<T>();

        return resolved;
    }

    public static void RegisterType(Type from, Type to)
    {
        Container.RegisterType(from, to);
    }
}

您应该删除代码中的if (Container.IsRegistered<T>()) ,因为对于您请求的每个存储库,这将返回false 诸如IRepository<string>IRepository<User>等的混合存储库未在容器中仅在IRepository<T>的通用版本中注册。

如果要返回null ,则在Container.Resolve周围使用try-catch-block,以便在发生异常时将resolve设置为null。

public static T Resolve<T>()
{
    T resolved;

    //if (Container.IsRegistered<T>()) 
    try{
      resolved = Container.Resolve<T>();
    }
    catch(Exception){
      resolved = default(T);
    }
    return resolved;
}

我用Unity做了这个小测试,试图理解你的问题(我必须GetById改变一下GetById方法)。 但是,它按预期工作,打印Type: System.DateTime

public interface IRepository<T>
{
    T GetById(int id);
}
public class Repository<T> : IRepository<T>
{
    public T GetById(int id)
    {
        Console.WriteLine("Type: " + typeof(T));
        return default(T);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();
        container.RegisterType(typeof(IRepository<>), typeof(Repository<>));

        IRepository<DateTime> iRepository = container.Resolve<IRepository<DateTime>>();

        iRepository.GetById(4);
        Console.ReadLine();
    }
}

我喜欢Jehof和ThB0Y的回答。 但我不喜欢捕捉异常。 我编写了自己的IsRegisteredInternal方法来检查未解析的泛型。

public static T Resolve<T>()
    {
        T ret = default(T);

        if (IsRegisteredInternal<T>())
        {
            ret = Container.Resolve<T>();
        }

        return ret;
    }

    private static bool IsRegisteredInternal<T>()
    {
        if (Container.IsRegistered<T>())
            return true;
        if (typeof(T).IsGenericType)
        {
            return Container.IsRegistered(typeof(T).GetGenericTypeDefinition());
        }
        return false;
    }

注意:IsRegistered()通过Container.Registrations进行枚举

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM