与构造函数链接的Ninject绑定问题

时间:2012-05-22 22:41:16

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

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

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

基本上我的申请目前正在进行

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

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

控制器 - >新的工作单位 - > SingletonDatabase,(New Repositories-> SingletonDatabase)

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

对于长文本感到抱歉,我不确定是否可以在没有我的代码片段的情况下获得重点,并且我的说法有些疏忽。

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...
}

Controller Constructor:

public IUserServices _userServices { get; set; }

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

1 个答案:

答案 0 :(得分:0)

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