为Asp.net Mvc应用程序使用单个Repository实例有什么好处吗?

时间:2009-06-11 10:44:59

标签: asp.net-mvc

CarTrackr project中,它使用一些技术,为Asp.net Mvc网站中的所有请求仅创建1个存储库实例,并使用UnityControllerFactory类来管理所有存储库实例(发送到请求的控制器)。

与每个请求创建新的存储库实例相比,使用单个存储库实例有什么好处吗?

我知道,这可能会提高整体表现。但是,它会导致任何交通问题吗?

部分Global.asax

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        RegisterDependencies();
    }

    protected static void RegisterDependencies() {
        IUnityContainer container = new UnityContainer();

        // Registrations
        container.RegisterType<IUserRepository, UserRepository>(new ContextLifetimeManager<IUserRepository>());
        container.RegisterType<ICarRepository, CarRepository>(new ContextLifetimeManager<ICarRepository>());

        // Set controller factory
        ControllerBuilder.Current.SetControllerFactory(
            new UnityControllerFactory(container)    
        );
    }
}

部分CarController.cs

[Authorize]
public class CarController : Controller
{
    private IUserRepository UserRepository;
    private ICarRepository CarRepository;

    public CarController(IUserRepository userRepository, ICarRepository carRepository)
    {
        UserRepository = userRepository;
        CarRepository = carRepository;
    }
}

谢谢,

3 个答案:

答案 0 :(得分:3)

每个请求创建一个存储库实例本身不应导致任何性能问题;存储库通常很浅,当需要访问数据时,连接池之类的东西可以最大限度地降低建立实际连接的成本。对象创建是非常便宜的,特别是对于像Web请求这样的短期内容,其中对象在仍然处于“零代”时被收集。

关于是否每个实例都有一个存储库或存储库 - 这取决于存储库;-p

最大的问题是:您的存储库线程安全吗?如果不是:每个请求一个。

即使它是;如果您的存储库本身保留了类似LINQ-to-SQL DataContext(您以某种方式同步)的内容,那么如果您保持长期,特别是身份,那么您就会遇到大问题经理。您将很快使用大量内存获得过时的结果。远非理想。

使用单个存储库实例,您可能最终会遇到大量阻塞,试图获得线程安全性。这可以降低吞吐量。相反,数据库本身具有实现粒度锁的好方法 - 当您考虑到并发请求通常会查看单独的表等时,这一点特别有用 - 因此在数据库层没有阻塞。这只是非常在存储库层很难做到 - 所以你可能不得不同步整个“fetch” - 非常糟糕。

IMO,在大多数情况下,每个请求一个都没问题。如果要缓存数据,请单独执行 - 即不在存储库实例上直接

答案 1 :(得分:2)

我认为你误解了ContextLifeTimeManager发生的事情。通过将管理器传递给Register()方法,告诉Unity将存储库实例的缓存范围设置为HttpContext。

说:

实际上是不正确的
  

它使用一些技术,只为Asp.net中的所有请求创建一个存储库实例&gt; Mvc网站

没有存储库单例。 Unity正在为每个请求创建一个。听起来这实际上是你想要的行为。

当管理器的作用域设置为HttpContext时,容器会向HttpContext查找所请求类型的现有实例(在本例中为您的存储库)。由于HttpContext在每个请求中都是新鲜的,因此容器将不具有此实例,因此将创建一个新实例。

当你问:

  

使用单身是否有任何好处   与之比较时的存储库实例   每次创建新的存储库实例   请求?

没有

就交易问题而言:线程将成为一个问题。 CarRepository似乎使用Linq2Sql或Linq2Entities。它的ctor需要一个有效的datacontext。 DataContext不是线程安全的。如果datacontext存储在高于当前请求的范围内,则会出现问题。

答案 2 :(得分:0)

使用新的ContextLifetimeManager());,存储库的生命周期仅限于一个请求。这意味着每次存储库的evry请求都会被实例化(如果需要),并在响应发送到客户端后销毁。