Ninject辛格尔顿对MVC数据仓库 [英] Ninject Singleton for MVC Data Repository

查看:107
本文介绍了Ninject辛格尔顿对MVC数据仓库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我MVC3应用程序我有这是由我的所有控制器引用给他们访问数据层的IDataRepository接口。还有一个DataRepository类,这是工具IDataRepository特定数据源(一个nHydrate衍生实体框架,在我的情况)。该DataRepository类需要一个参数,它是连接字符串到基础数据库。

In my MVC3 app I have an IDataRepository interface which is referenced by all my controllers to give them access to the data layer. There's also a DataRepository class which is implements IDataRepository for a particular data source (an nHydrate-derived Entity Framework, in my case). The DataRepository class takes a single argument, which is the connection string to the underlying database.

以下绑定:

kernel.Bind<IDataRepository>()
    .To<DataRepository>()
    .WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());

今天,我读到nInject范围界定,我想,这样DatabaseRepository只有一个实例为每个请求(我想这将是更有效的,虽然与EF我没有得到创建它会安排有用的东西当然)。

Today I read about nInject scoping, and I thought it would be useful to arrange things so that only one instance of DatabaseRepository got created for each request (I'm thinking this will be more efficient, although with EF I'm not sure).

不幸的是,我似乎无法弄清楚如何正确执行模式。例如,这不起作用:

Unfortunately, I can't seem to figure out how to implement the pattern correctly. For example, this doesn't work:

kernel.Bind<DataRepository>()
    .ToSelf()
    .InRequestScope()
    .WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());

kernel.Bind<IDataRepository>()
    .To<DataRepository>();

我的想法是,这将创造DataRepository,这将在以IDataRepository所有引用被使用的只是一个实例。该错误消息抱怨敌不过能为的connectionString参数可以发现,和DataRepository不是自我绑定。我尝试了一些变化,但是当我能得到它的工作没有得到遵循Singleton模式(即我可以说,正在创建DataRepository的多个实例,调试器看到的)。

My thinking was that this would create just a single instance of DataRepository, which would be used in all references to IDataRepository. The error message complained that no match could be found for the connectionString parameter, and DataRepository was not self-bindable. I tried some variations, but when I could get it to work the singleton pattern wasn't being followed (i.e., I could see in the debugger that multiple instances of DataRepository were being created).

我缺少明显的东西在这里:)

I'm missing something obvious here :).

--- ---补遗
不幸的是,建议不从相同的请求中被创建prevent多个实例

--- Addendum --- Unfortunately, the suggestion doesn't prevent multiple instances from being created within the same request.

需要明确的是,我的尝试是:

To be clear, what I tried was:

public class BaseControllerModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDataRepository>().To<DataRepository>().InRequestScope()
        .WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());
    }
}

和我是什么监测​​是构造:

and what I was monitoring was the constructor:

public DataRepository( string connectionString )
    : base(connectionString)
{
}

- 更多信息#2 -

-- More info #2 --

下面是类Ninject是解决我的布局:

Here's the layout of the classes Ninject is resolving for me:

public class DataRepositoryBase
{
    protected DataRepositoryBase( string connectionString )
    {}
    public static string GetConnectionString() {}
}
public class DataRepository : DataRepositoryBase, IDataRepository
{
    public DataRepository( string connectionString )
        : base(connectionString)
    {}
}

我已经离开了实施细则,但希望这描绘了一个更好的画面。

I've left out the implementation details, but hopefully this paints a better picture.

在展望这一点,我不知道如果我造成的问题通过的ConnectionString构造函数的参数为​​DataRepository和其基类DataRepositoryBase。不会Ninject解决的connectionString在调用基类的构造函数?

Looking this over, I wonder if I'm causing problems by making connectionString a constructor parameter for both DataRepository and its base class DataRepositoryBase. Wouldn't Ninject resolve connectionString in the call the base class constructor?

P.S。我意识到为时已晚,我不需要DataRepositoryBase,因为它的功能可以合并到DataRepository。我这样做,但我仍然具有DataRepository构造多次调用这似乎是一个请求。

p.s. I belatedly realized I don't need DataRepositoryBase, because its functionality can be merged into DataRepository. I've done that, but I'm still having the constructor for DataRepository called multiple times in what appears to be one request.

p2.s。为了好玩,我试图宣布在Ninject绑定定义InSingletonScope()。这工作 - 为DataRepository构造函数现在只被调用一次,当第一次访问应用程序。但我不认为这是一个不错的主意,有在MVC应用程序单身。这似乎是这将导致应用程序的状态在内存中得到锁定。

p2.s. For fun, I tried declaring InSingletonScope() in the Ninject binding definition. That worked -- the constructor for DataRepository now only gets called once, when the app is first accessed. But I don't think it's a good idea to have singletons in an MVC app. It seems like that would cause the "state" of the app to get "locked" in memory.

---然而更多信息---

--- yet more info ---

这个问题似乎与我设计我的MVC应用程序的方式。我认为是从浏览器到服务器的单个请求往往导致多个请求按顺序被处理(我在看BeginRequest事件在MvcApplication类被解雇)。好像每次我过渡到正在生成一个新的请求不同的控制器(例如,通过一个RedirectToAction)。我想这是有道理的,但它意味着Ninject的InRequestScope将不太做我想做的。

The problem seems to be with the way I've designed my MVC app. What I assumed was a single request from the browser back to the server often results in multiple requests being processed in sequence (I'm watching the BeginRequest event being fired in the MvcApplication class). It seems like every time I transition to a different controller a new request is being generated (e.g., via a RedirectToAction). I guess this makes sense, but it means Ninject's InRequestScope won't quite do what I want.

但是,这也使我怀疑我刚刚设计了应用程序错误。好像我应该把所有的可能被调用上的浏览器调用到单个控制器的操作方法。相反,我已经组织了它们如何适应我的应用程序的概念模型的操作方法。

But it also makes me wonder if I've just designed the app wrong. It seems like I should be grouping all of the action methods that might get invoked on a browser call into a single controller. Instead, I've organized the action methods by how they fit into the conceptual model for my app.

推荐答案

这两个绑定说:
DataRepository 请求重用该实例的请求中所有出现,并设置连接字符串DataRepositoryBase.GetConnectionString()。

These two bindings say: When a DataRepository is requested reuse the instance for all occurances within the request and set the connection string to DataRepositoryBase.GetConnectionString().

但是,当一个 IDataRepository 要求,为每次数创建一个新的实例,让Ninject决定什么它注入连接字符串。

But when a IDataRepository is requested, create a new instance for every occurance and let Ninject decide what it injects for the connection string.

您真正想要的是通过添加 InRequestScope 来的第一个code片段。

What you really want is done by adding InRequestScope to the first code snippet.

这篇关于Ninject辛格尔顿对MVC数据仓库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆