2010-04-14 2 views
0

"Framework.DataAccess", "Framework.DataAccess.NHibernateProvider"및 "Company.DataAccess"의 세 가지 어셈블리가 있습니다.가능한 공급자로 팩토리를 구성하려면 어떻게합니까?

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

내가 원하는 :

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의 기본 인터페이스를 정의 어셈블리 "Framework.DataAccess"내부에서, 나는 (발견의 잘못된 구현) 내 공장 이 어셈블리를 포괄적으로 유지하면서 참조하지 않아야합니다. 이것은 내 기본 데이터 액세스 어셈블리입니다.

그런 다음 NHibernate의 접근 방식을 사용하여 위의 IReadDao를 구현하는 NHibernate 공급자의 어셈블리가 있습니다. 이 어셈블리는 "Framework.DataAccess"어셈블리를 참조합니다. 마침내

public class NHibernateDao<T> : IReadDao<T> 
{ 
    public NHibernateDao() 
    { 
    } 

    public virtual IEnumerable<T> GetAll() 
    { 
     throw new NotImplementedException(); 
    } 
} 

, 내가 NHibernate에 제공 및 참조 모두 이전에 본 어셈블리의 기본 구현을 재정의 할 수 있습니다 "Company.DataAccess"어셈블리를 보유하고 있습니다.

내가 쓸 수 있도록하려면
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

짧은 답변 : 서비스 로케이터로 컨테이너를 사용하지 마십시오. 구글 "서비스 패턴 탐지기" –

+0

어떤 제안? 몇 가지 데이터 액세스 구현이 있습니다. CsvProvider, NHibernateProvider 및 XmlProvider. 도메인 엔티티에 따라 다른 기본 구현을 갖습니다. 컨테이너/공장을 어떻게 분리/구성 할 수 있습니까? –

+0

한 가지 더 :이 요구 사항은 엔티티가 하나의 데이터 저장소 만 갖도록 보장합니다. 즉, 각 엔티티에는 하나의 데이터 액세스 구현 유형 만 있습니다. –

답변

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; 
    } 
} 
관련 문제