【问题标题】:Ninject Binding Issue with Constructor Chaining构造函数链接的 Ninject 绑定问题
【发布时间】:2012-05-29 11:34:53
【问题描述】:

我有一个使用实体框架和 Ninject v2.2 的 MVC3 项目,并遵循工作单元模式,服务层包装了我的存储库。

查看下面的代码后,希望很明显 Ninject 正在使用构造函数链接来注入正确的类。它目前在我的应用程序中运行良好,但是我需要将 IDatabase 的实例绑定到具有不同范围的 MyDatabase,例如 InSingletonScope() 或 InNamedScope(),而不是 InRequestScope()。我知道我可以使用 [Named("MyDatabaseScope")] 属性来自定义注入哪个 IDatabase 对象,但是似乎对于我的代码结构,如果我想注入我的 SingletonScoped 实例,我将不得不重新创建一个新的 Abstract和我的工作单元、我的服务和我所有的存储库的具体实现,然后将链接下来。

基本上我的应用程序目前正在运行

控制器 -> 工作单元 -> 数据库,(存储库 -> 数据库)

如果我必须更改我的数据库绑定,我现在必须在当前链之外创建另一个链:

Controller -> New Unit of Work -> SingletonDatabase, (New Repositories-> SingletonDatabase)

这似乎完全击败了 DRY 原则。有没有办法从 Controller Constructor 通知 Ninject 在进行构造函数链接时它应该使用我的单例(或命名绑定)而不是我的请求范围绑定,而不必使用命名属性或新的属性重新创建我的所有类接口?

抱歉,文字太长了,如果没有我的代码 sn-ps 和我有些漫不经心的解释,我不确定我是否能理解这一点。

Ninject 模块加载函数:

..snip..
Bind<IUserServices>().To<UserServices>();
Bind<IBaseServices>().To<BaseServices>();
Bind<IUserRepository>().To<UserRepository>();
Bind(typeof (IRepository<>)).To(typeof (RepositoryBase<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabase>().To<MyDatabase>().InRequestScope();

//This is my problem:
//Bind<IDatabase>().To<MySingletonDatabase>().InSingletonScope();

工作单元实施构造器:

public class UnitOfWork : IUnitOfWork
{
    private IDatabase _database;

    public UnitOfWork(IDatabase database,
                      IUserRepository userRepository,
                      IPeopleRepository peopleRepository,
        )
    {
        this._database = database;
        this.UserRepository = userRepository;
        this.PeopleRepository = peopleRepository;
    }

    protected IDatabase Database
    {
        get { return _database; }
    }

    ...snip...
}

用户服务层实现构造器:

public class UserServices : BaseServices, IUserServices
{
    private IUnitOfWork _uow;

    public UserServices(IUnitOfWork uow)
        : base(uow)
    {
        _uow = uow;
    }
    ...snip...
}

用户存储库构造函数:

public class UserRepository : RepositoryBase<User>, IUserRepository
{
    public UserRepository(IDatabase database)
        : base(database)
    {
    }
    ...snip...
}

控制器构造函数:

public IUserServices _userServices { get; set; }

    public ActivityController(IUserServices userServices)
    {
        _userServices = userServices;
    }
}

【问题讨论】:

  • 如果数据库是 EF 上下文的包装器,它不应该使用除 RequestScope 之外的任何东西。
  • 我目前正在将 InRequestScope 用于我的主要上下文对象,但似乎我需要将 InNamedScope 用于将与 asynchronous task (that was answered on SO) 一起使用的不同上下文对象我只是使用 InSingletonScope 作为使用不同范围的数据库上下文的示例

标签: asp.net-mvc-3 entity-framework repository ninject unit-of-work


【解决方案1】:

使用 Ninject 3.0.0 你可以使用WhenAnyAncestrorNamed("Some name") 但是如果你需要运行异步的东西你应该把你的应用程序分成一个 web 前端和一个服务器后端。这可以让很多事情变得更容易。

【讨论】:

  • 我的应用程序只有一个需要异步运行的函数,它解析一个大的xml文档并将其导入数据库。它不经常使用,因此仅针对此任务重组代码库似乎有点过头了。 Ninject 2.2中是否有类似WhenAnyAncestorNamed的东西?
  • 否 - 但你为什么不升级?应该不会花很长时间。
猜你喜欢
  • 2019-10-26
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 2012-08-27
相关资源
最近更新 更多