C# Unity 对于泛型接口的支持

最近和小伙伴们在做一个前台小框架, 已经有些人用起来了。 但是之前框架没有引入 Ioc, 所以用户实现我们框架开放出去的接口后,我们只能通过反射来获取用户的实现类。这样一个问题就是我们虽然定义了接口, 但其实我们依然依赖于用户的实现,同时框架启动异常的慢。 所以我们打算使用开源 Ioc 框架来把完成依赖注入的动作。 我们就完全关心我们自己的接口, 然后用户可以自己把实现类注入到框架中来,这样不仅移除了依赖,同是也砍掉了反射,可以加快加载速度。

因为开放的接口中定义了泛型接口,所以选中支持泛型接口的 Unity 来完成 Ioc 功能。 下面一步步实现一个简单的 Unity 泛型接口实例。 

首先定义三个项目:

  1. UnityPrimer 框架代码
  2. UnityPrimerClient 框架用户代码
  3. UnityPrimerInterfaces 框架接口

项目结构如图:


框架接口包含:

  1. 实体接口
    1. namespace UnityPrimerInterfaces.Interfaces
      {
          public interface IModel
          {
              string Name { get; set; }
          }
      }


  2. 泛型接口
    1. namespace UnityPrimerInterfaces.Interfaces
      {
          public interface IEnricher<T> where T:IModel
          {
              T StringToModel(string message);
              string ModelToString(T model);
          }
      }



框架用户实现代码:实现框架定义的接口,并且把实现实例注入到容器中。

  1. 接口实现
    1.  public class Model :IModel
          {
              private string name;
              public string Name
              {
                  get
                  {
                      return name;
                  }
                  set
                  {
                      name = value;
                  }
              }
          }


    2. public class Enricher<T> : IEnricher<T> where T:IModel
          {
              public T StringToModel(string message)
              {
                  var model =new Model() { Name = message };
                  return (T)((IModel)model);
              }
      
              public string ModelToString(T model)
              {
                  return model.Name;
              }
          }


  2. 注册器
    1. namespace UnityPrimerClient
      {
          public class Register
          {
              public static IUnityContainer Container;
              public static void Regist()
              {
                  Container = new UnityContainer();
      
                  Container.RegisterType(typeof(IEnricher<>), typeof(Enricher<>), "Sample");
                  //Container.RegisterType(typeof(IEnricher<IModel>), typeof(Enricher<Model>), "Sample");
                  //Container.RegisterInstance<IEnricher<IModel>>(new Enricher<Model>());
              }
      
          }
      }


框架代码:框架从容器中获取用户实现的对象,并进行操作。 

  1. namespace UnityPrimer
    {
        class Program
        {
            static void Main(string[] args)
            {
                Register.Regist();
    
                var enricher = Register.Container.Resolve<IEnricher<IModel>>("Sample");
    
                IModel model = enricher.StringToModel("SampleModel");
                Console.WriteLine(enricher.ModelToString(model));
                Console.ReadLine();
    
            }
        }
    }


对于 Unity 来说,最容易出错的部分,就是 register 和 resolve 的时候。同是对于泛型接口,泛型约束会导致resolve失败。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。