如何使用可能的提供者配置工厂?
我有三个程序集:“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”程序集。
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 配置文件中读取它。
所以,我的问题是:如何从外部配置这个工厂以使用特定的提供程序作为我的默认实现和客户端实现?
I have three assemblies: "Framework.DataAccess", "Framework.DataAccess.NHibernateProvider" and "Company.DataAccess". Inside the assembly "Framework.DataAccess", I have my factory (with the wrong implementation of discovery):
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>();
}
}
This assembly also defines the base interface for data access IReadDao:
public interface IReadDao<T>
{
IEnumerable<T> GetAll();
}
I want to keep this assembly generic and with no references. This is my base data access assembly.
Then I have the NHibernate provider's assembly, which implements the above IReadDao using NHibernate's approach. This assembly references the "Framework.DataAccess" assembly.
public class NHibernateDao<T> : IReadDao<T>
{
public NHibernateDao()
{
}
public virtual IEnumerable<T> GetAll()
{
throw new NotImplementedException();
}
}
At last, I have the "Company.DataAccess" assembly, which can override the default implementation of NHibernate provider and references both previously seen assemblies.
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();
}
}
I want to be able to write...
IRead<Product> dao = DaoFactory.Create<IRead<Product>>();
... and then get the ProductDao implementation. But I can't hold inside my base data access any reference to specific assemblies! My initial idea was to read that from a xml config file.
So, my question is: How can I externally configure this factory to use a specific provider as my default implementation and my client implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
知道了。
我正在使用 IWindsorInstaller 来实现包:
在 Framework.DataAccess 中,我的容器现在是:
Got it.
I am using IWindsorInstaller to implement packages:
And at Framework.DataAccess, my container is now: