У меня есть три сборки: «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, которая реализует вышеупомянутый IReadDao, используя подход NHibernate. Эта сборка ссылается на сборку «Framework.DataAccess».
public class NHibernateDao<T> : IReadDao<T>
{
public NHibernateDao()
{
}
public virtual IEnumerable<T> GetAll()
{
throw new NotImplementedException();
}
}
Наконец, у меня есть сборка "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.
Итак, мой вопрос: как я могу внешне настроить эту фабрику для использования конкретного поставщика в качестве реализации по умолчанию и реализации клиента?