一个控制器中的许多存储库并初始化数据库连接

时间:2012-12-08 14:00:08

标签: asp.net-mvc

我想使用Repository Pattern(我知道我可以使用Unit of Work Pattern但我想在这里使用Repository Pattern)。因此,在每个存储库类中,我都有对特定表的查询,例如:

public class NotesRepository : INotesRepository, IDisposable
{
    private DatabaseContext context;

    public NotesRepository(DatabaseContext context)
    {
        this.context = context;
    }

    public IQueryable<Notes> GetAllNotes()
    {
        return (from x in context.Notes
                select x);
    }
}

另一个存储库示例:

public class CommentsRepository : ICommentsRepository, IDisposable
{
    private DatabaseContext context;

    public CommentsRepository(DatabaseContext context)
    {
        this.context = context;
    }

    public IQueryable<Comments> GetAllComments()
    {
        return (from x in context.Comments
                select x);
    }
}

现在我想在一个控制器中使用这两个存储库。因此,使用Repository Pattern我在控制器构造函数中初始化数据库连接并将其传递给每个存储库,对吗?例如:

public class HomeController : Controller
{
    private INotesRepository NotesRepository;
    private ICommentsRepository CommentsRepository;

    public HomeController()
    {
        DatabaseContext db = new DatabaseContext();

        this.NotesRepository = new NotesRepository(db);
        this.CommentsRepository = new CommentsRepository(db);
    }

    // ........
}

3 个答案:

答案 0 :(得分:1)

我认为你应该至少更进一步,让Controller将存储库作为构造函数中的依赖项。这意味着您将在自定义ControllerFactory(在ASP.NET MVC和MVC2中使用)或DependencyResolver(在ASP.NET MVC3 IIRC中引入)中创建Controller和Repository实例;如果转移到IoC容器)。 DatabaseContext通常在Web应用程序中按HttpRequest创建,以便在请求期间维护相同的UnitOfWork。如果您正在使用IoC容器,则可以轻松完成,因为对此的支持已内置于所有主要容器中。如果您是手动执行此操作,则必须连接一些机制,以便在DatabaseContextApplication.BeginRequest事件中创建和处置EndRequest

为简单起见,我将为您提供一个ASP.NET MVC示例,而不使用容器并且每个DatabaseContext有一个Controller个实例。当Controller“释放”时,不会释放DatabaseContext。

public class HomeController : Controller
{
    private INotesRepository notesRepository;
    private ICommentsRepository commentsRepository;

    public HomeController(INotesRepository notesRepostory, 
        ICommentsRepository commentsRepository)
    {
        this.notesRepository = notesRepository;
        this.commentsRepository = commentsRepository;
    }
}

public class MyControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return base.GetControllerInstance(requestContext, controllerType);

        DatabaseContext db = new DatabaseContext();
        //Here you should have logic to determine which 
        //type of controller to create
        return new HomeController(new NotesRepository(db), 
            new CommentsRepository(db));
    }
}

在Global.asax Application.Start事件处理程序中:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

如果你去集装箱航线,有很多IoC与MVC以及你最喜欢的Container品牌的例子。

使用Inversion of Control的优势在于应用程序变得松散耦合,更易于更改和维护。

答案 1 :(得分:0)

当您使用存储库时,您希望将数据访问代码从业务逻辑中抽象出来,因此处理控制器内部的连接并不是很干净。也许存储库不是你需要的......

答案 2 :(得分:-1)

这里的情况非常适合使用依赖注入(DatabaseContextNotesRepositoryCommentsRepository的依赖关系。

这很容易通过像Ninject这样的依赖注入容器来解决。