Ninject NHibernate 面向插件的架构

Ninject NHibernate on plugin oriented architecture

根据 COMPOSITION ROOT 模式,我必须构建尽可能靠近应用程序入口点的所有依赖关系图。

我的架构是面向插件的。所以,如果有人想扩展我的基本系统,他可以。

例如,在我的基本系统中我有这样的结构:

  1. 视图层
  2. 服务层
  3. 数据访问层
  4. 模型层

在 DAL 中,我公开了一些 classes,例如:

  1. IRepository
  2. NHibernateRepository
  3. 产品库

所以,如果一个插件想要将我的基础产品 class 扩展到 ExtendedProduct,然后创建继承自 NHibernateRepository 的 ExtendedProductRepository。

问题是: 如何使用 NInject 从我的基本系统实例化 NHibernateRepository 实例?

所以,我知道要做的第一件事是构建图形依赖关系:

using (var kernel = new StandardKernel())
{
    kernel.Bind(b => b.FromAssembliesMatching("*")
    .SelectAllClasses()
    .InheritedFrom<IRepository>()
    .BindAllInterfaces());
}

但是,我发现当我执行类似以下内容时:

kernel.GetAll<IRepository>()

它会return给我一个 ProductRepository 实例,以及两个 IRepository 对象下的另一个 ProductExtendedRepository。

那么,如何从我的基本系统中保存 ProductExtended 对象...? 另一个问题是,我如何在我的插件中注入一个对象实例,或者,插件如何自动注入一些基本系统程序集的实例?

谢谢大家。 非常感谢您的帮助。

我将此模式用于基于 NHibernate 的项目:

public interface IRepository<T> : IQueryable<T>
{
    T Get(int id);
    void Save(T item);
    void Delete(T item);
}

public class NHibernateRepository<ModelType> : IRepository<ModelType>
    where ModelType : class
{
     // implementation
}

然后...

public interface IProductRepository : IRepository<Product> 
{
    // product specific data access methods
}

public class ProductRepository : NHibernateRepository<Product>, IProductRepository
{
    // implementation 
}

... 在 Ninject 模块中:

Bind(typeof(IRepository<>)).To(typeof(NHibernateRepository<>));
Bind<IProductRepository>().To<ProductRepository>();

然后您可以请求基本功能,例如:

public Constructor(IRepository<Product> repo) { ... }

或特定产品存储库功能:

public Constructor(IProductRepository repo) { ... }

您的插件可以获得基本功能并且无需注册任何内容:

public PluginConstructor(IRepository<ProductExtended> repo { ... }

或创建自己的存储库并将它们注册到 Ninject 模块中。

谢谢戴夫。

太完美了。我试试看

但是,我如何保存、获取或更新(无论哪种 IRepository 方法)...来自我的基本系统的 ExtendedProduct 实例?

思考如下:

public interface BasePlugin<T> {...}

在另一个程序集中:

public class PluginExtendedProduct : BasePlugin<ExtendedProduct>
{
    public PluginExtendedProduct (IRepository<ExtendedProduct> repo { ... }
}

我很头疼的是如何在我的基本系统中创建(因此,ExtendedProduct)的实例以调用使用 IRepository 的方法 PluginExtendedProduct。

不知道自己解释的好不好...

谢谢大家。