如何使用可能的提供程序配置Factory?

时间:2010-04-14 14:36:06

标签: .net inversion-of-control castle-windsor factory

我有三个程序集:“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配置文件中读取它。

所以,我的问题是:我如何在外部配置此工厂以使用特定的提供程序作为我的默认实现和我的客户端实现?

1 个答案:

答案 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;
    }
}
相关问题