Unity 在现在项目中,已经得到广泛使用。今天我们来看如何在XML配制文件配制泛型。如下我们这样的一个类型:

   1:      public interface IRepository<T> 
   2:      {
   3:          IUnitOfWork UnitOfWork { get; set; }
   4:          IQueryable<T> All();
   5:          IQueryable<T> Find(Expression<Func<T, bool>> expression);
   6:          void Attach(T entity);
   7:          void Add(T entity);
   8:          void Delete(T entity);
   9:          void Save();
  10:      }

            这是一个Repository模式,假设有以下的实现:

   1:      public class EFRepository<T> : IRepository<T> where T : class
   2:      {
   3:          public IUnitOfWork UnitOfWork { get; set; }
   4:          private IObjectSet<T> _objectset;
   5:          private IObjectSet<T> ObjectSet
   6:          {
   7:              get
   8:              {
   9:                  if (_objectset == null)
  10:                  {
  11:                      _objectset = UnitOfWork.Context.CreateObjectSet<T>();
  12:                  }
  13:                  return _objectset;
  14:              }
  15:          }
  16:   
  17:          public virtual IQueryable<T> All()
  18:          {
  19:              return ObjectSet.AsQueryable();
  20:          }
  21:   
  22:          public IQueryable<T> Find(Expression<Func<T, bool>> expression)
  23:          {
  24:              return ObjectSet.Where(expression).AsQueryable();
  25:          }
  26:   
  27:          public void Add(T entity)
  28:          {
  29:              ObjectSet.AddObject(entity);
  30:          }
  31:          
  32:          public void Attach(T entity)
  33:          {
  34:              ObjectSet.Attach(entity);
  35:          }
  36:   
  37:          public void Delete(T entity)
  38:          {
  39:              ObjectSet.DeleteObject(entity);
  40:          }
  41:   
  42:          public void Save()
  43:          {
  44:              UnitOfWork.Save();
  45:          }
  46:      }

在代码中注册是这样的:

   1:             container.RegisterType<IUnitOfWork, EFUnitOfWork>();
   2:              container.RegisterType<IRepository<Product>, EFRepository<Product>>();

好的,现在我们从配制文件读取:

   1:         private static IUnityContainer container;
   2:   
   3:         static ObjectFactory()
   4:         {
   5:              container = new UnityContainer();
   6:   
   7:              //container.RegisterType<IUnitOfWork, EFUnitOfWork>();
   8:              //container.RegisterType<IRepository<Product>, EFRepository<Product>>();
   9:   
  10:              string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EntLib.config.xml");
  11:              var map = new ExeConfigurationFileMap { ExeConfigFilename = path };
  12:   
  13:              System.Configuration.Configuration config
  14:                  = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
  15:              UnityConfigurationSection section
  16:                  = (UnityConfigurationSection)config.GetSection("unity");
  17:              section.Containers["DefContainer"].Configure(container);
  18:          }
  19:           
  20:          public static T GetInstance<T>()
  21:          {
  22:              return container.Resolve<T>();
  23:          }

关键的XML配制在这儿:

   1:  <configuration>
   2:    <configSections>
   3:      <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   4:    </configSections>
   5:    <unity>
   6:      <typeAliases>
   7:        <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
   8:        <typeAlias alias="transparentProxy" type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" />
   9:        <typeAlias alias="typeMatchingRule" type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception" />
  10:        <typeAlias alias="interception" type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception" />
  11:        <typeAlias alias="IRepository`1" type="TestEF4.IRepository`1,  TestEF4" />
  12:        <typeAlias alias="IUnitofwork" type="TestEF4.IUnitOfWork,  TestEF4" />
  13:      </typeAliases>
  14:      <containers>
  15:        <container name="DefContainer">
  16:          <types>
  17:            <type type="IUnitofwork"  mapTo="TestEF4.EFUnitOfWork, TestEF4">
  18:              <lifetime type="singleton" />
  19:            </type>
  20:            <type type="IRepository`1"  mapTo="TestEF4.EFRepository`1, TestEF4">
  21:              <lifetime type="singleton" />
  22:            </type>
  23:          </types>
  24:        </container>
  25:      </containers>
  26:    </unity>
  27:  </configuration>

注意加粗的字体就是我们泛型。让我们来测试一下:

   1:          [Test]
   2:          public void TestUnityGenericTypeConfig()
   3:          {
   4:              var productRepository = RepositoryHelper.GetProductRepository();
   5:              var totalentities = productRepository.All();
   6:   
   7:              Assert.IsNotNull(productRepository);
   8:              Assert.IsInstanceOf<ProductRepository>(productRepository);
   9:              Assert.IsInstanceOf<EFRepository<Product>>(productRepository.Repository);
  10:              Assert.IsInstanceOf<EFUnitOfWork>(productRepository.Repository.UnitOfWork);
  11:          }

一切OK了,这就实用使用配制文件实现DI解析泛型。希望对您开发有帮助。


作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog

posted on 2010-11-05 20:08  PetterLiu  阅读(3147)  评论(2编辑  收藏  举报