2010-04-14 48 views
0

我有三個程序集:「Framework.DataAccess」,「Framework.DataAccess.NHibernateProvider」和「Company.DataAccess」。裏面的組件「Framework.DataAccess」,我有我的廠(用錯誤執行發現):如何配置可能提供商的工廠?

public class DaoFactory 
{ 
    private static readonly object locker = new object(); 
    private static IWindsorContainer _daoContainer; 

    protected static IWindsorContainer DaoContainer 
    { 
     get 
     { 
      if (_daoContainer == null) 
      { 
       lock (locker) 
       { 
        if (_daoContainer != null) 
         return _daoContainer; 

        _daoContainer = new WindsorContainer(new XmlInterpreter()); 

        // THIS IS WRONG! THIS ASSEMBLY CANNOT KNOW ABOUT SPECIALIZATIONS! 
        _daoContainer.Register(
         AllTypes.FromAssemblyNamed("Company.DataAccess") 
          .BasedOn(typeof(IReadDao<>)).WithService.FromInterface(), 
         AllTypes.FromAssemblyNamed("Framework.DataAccess.NHibernateProvider") 
          .BasedOn(typeof(IReadDao<>)).WithService.Base());       
       } 
      } 

      return _daoContainer; 
     } 
    } 

    public static T Create<T>() 
     where T : IDao 
    { 
     return DaoContainer.Resolve<T>(); 
    } 
} 

此組件還定義了數據訪問IReadDao的基本接口:

public interface IReadDao<T> 
{ 
    IEnumerable<T> GetAll(); 
} 

我想保持這個程序集通用並且沒有引用。這是我的基本數據訪問程序集。

然後我有NHibernate提供程序的程序集,它使用NHibernate的方法實現上述IReadDao。該程序集引用「Framework.DataAccess」程序集。最後,我有「Company.DataAccess」程序集,它可以覆蓋NHibernate提供程序的默認實現,並引用以前看到的程序集。

public interface IProductDao : IReadDao<Product> 
{ 
    Product GetByName(string name); 
} 

public class ProductDao : NHibernateDao<Product>, IProductDao 
{ 
    public override IEnumerable<Product> GetAll() 
    { 
     throw new NotImplementedException("new one!"); 
    } 

    public Product GetByName(string name) 
    { 
     throw new NotImplementedException(); 
    } 
} 

我希望能夠寫...

IRead<Product> dao = DaoFactory.Create<IRead<Product>>(); 

...然後得到ProductDao的實現。但是我無法保存我的基礎數據訪問任何對特定程序集的引用!我最初的想法是從XML配置文件中讀取。

所以,我的問題是:我如何外部配置這個工廠使用特定的提供程序作爲我的默認實現和我的客戶端實現?

+1

簡短的回答:不使用容器作爲一個服務定位器。谷歌「服務定位器反模式」 – 2010-04-14 16:32:29

+0

任何建議?我有一些數據訪問實現,例如CsvProvider,NHibernateProvider和XmlProvider。根據域實體,我將有不同的默認實現。我怎樣才能分離/配置容器/工廠? – 2010-04-14 17:00:40

+0

還有一件事:該要求保證我一個實體只有一個數據存儲,這意味着每個實體只有一個數據訪問實現類型。 – 2010-04-14 17:03:27

回答

0

明白了。

我使用IWindsorInstaller實行包:

public class TestDaoInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      AllTypes.FromAssemblyNamed("Company.DataAccess") 
       .BasedOn(typeof(IReadDao<>)).WithService.FromInterface(), 
      AllTypes.FromAssemblyNamed("Framework.DataAccess.NHibernate") 
       .BasedOn(typeof(IReadDao<>)).WithService.Base()); 
    } 
} 

而在Framework.DataAccess,我的容器是現在:

protected static IWindsorContainer DaoContainer 
{ 
    get 
    { 
     if (_daoContainer == null) 
     { 
      lock (locker) 
      { 
       if (_daoContainer != null) 
        return _daoContainer; 

       _daoContainer = new WindsorContainer(new XmlInterpreter()); 
       IWindsorInstaller[] daoInstallers = _daoContainer.ResolveAll<IWindsorInstaller>(); 
       foreach (IWindsorInstaller daoInstaller in daoInstallers) 
        _daoContainer.Install(daoInstaller); 

      } 
     } 

     return _daoContainer; 
    } 
}