【问题标题】:Ninject NHibernate on plugin oriented architectureNinject NHibernate 在面向插件的架构上
【发布时间】:2015-07-08 09:29:05
【问题描述】:

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

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

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

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

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

  1. IRepository
  2. NHibernateRepository
  3. 产品存储库

所以,如果一个插件想要将我的基本 Product 类扩展为 ExtendedProduct,然后创建继承自 NHibernateRepository 的 ExtendedProductRepository。

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

所以,我知道首先要做的是构建图依赖关系:

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

但是,我发现当我执行以下操作时:

kernel.GetAll<IRepository>()

它将返回一个 ProductRepository 实例,以及两个 IRepository 对象下的另一个 ProductExtendedRepository。

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

谢谢大家。 我将不胜感激。

【问题讨论】:

    标签: nhibernate ninject


    【解决方案1】:

    我将此模式用于基于 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 
    }
    

    ...在忍者模块中:

    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 模块中。

    【讨论】:

      【解决方案2】:

      谢谢戴夫。

      完美。我试试看。

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

      想一想:

      public interface BasePlugin<T> {...}
      

      在另一个程序集中:

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

      我最头疼的是如何在我的基础系统中创建一个 (so, ExtendedProduct) 的实例,以便调用使用 IRepository 的方法 PluginExtendedProduct。

      我不知道我是否解释得很好......

      谢谢大家。

      【讨论】:

      • 这正是你的做法。 IRepository&lt;ExtendedProduct&gt; 将在没有任何额外绑定的情况下被注入,因为 IRepository&lt;&gt; 已被绑定。
      • 仅供参考,您通常会将问题作为评论添加到答案中,而不是发布另一个答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 2012-06-12
      • 1970-01-01
      • 2011-05-24
      • 2023-03-04
      相关资源
      最近更新 更多