首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖注入

依赖注入
EN

Stack Overflow用户
提问于 2011-03-03 02:32:20
回答 3查看 1.9K关注 0票数 3

我们正在构建一个windows桌面应用程序(不是基于web的),并试图提出实现存储库和UnitOfWork模式的最佳方法。

在一个典型的Asp.Net Mvc应用程序中,您的存储库被注入数据上下文,服务被注入存储库,最后控制器被注入服务,一切正常如果您没有遇到任何异常,您将提交更改。

在windows forms/wpf应用程序中,不建议使用单个数据上下文( Oren在MSDN上有一篇关于这方面的文章),因此我们决定在演示者处创建数据上下文。我们使用的是Linq2SQl,基于视图我们有两个不同的数据库可供使用。

目前我有以下实现

代码语言:javascript
复制
public interface IRepository<T> where T : class
    {
        IEnumerable<T> Find(Expression<Func<T, bool>> where);
        T Single(Expression<Func<T, bool>> where);
        ...
     }

public class Repository<T> : IRepository<T> where T : class
    {
        private readonly Table<T> _table;

        public Repository(DataContext dataContext)
        {
            _table = dataContext.GetTable<T>();
        }
   }

public Class TodoService :ITodoService
{
       IRepository<Todo> _todoRepository;
       public TodoService(DataContext dataContext)
       {
           _todoRepository = new Repository<Todo>(dataContext)
       }
       ...
}

}

// UI的Presenter

代码语言:javascript
复制
public class TodoPresenter
{
    public void Save()
    {
       Using (DataContext dataContext = DataContextFactory.GetNewContextForDatabase1())
       {
           ITodoService service = new TodoService(dataContext);
            ...
           service.Save(..);
           dataContext.SubmitChanges();           
       }
    }

}

我希望将presenter与服务解耦,并希望在请求ITodoService时注入TodoService,但由于两个原因,我无法注入数据上下文,因为我必须基于数据库做出决定,或者甚至无法在应用程序级别维护数据上下文,即使我们只有一个数据库是windows应用程序(许多视图在应用程序中一次打开为选项卡),并且没有数据上下文,我无法创建存储库类,也无法注入服务。

有没有关于如何在这种情况下实现解耦的想法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-03 13:40:39

代码语言:javascript
复制
 > I cannot inject data context

但是也许您可以注入一个工厂方法来创建上下文和服务

代码语言:javascript
复制
public class TodoPresenter
{
    private Func<DataContext> dataContextFactory;
    private Func<DataContext, ITodoService> serviceFactory;

    // created with new TodoPresenter(DataContextFactory.GetNewContextForDatabase1(), 
    //                   dc => new TodoService(dc, 
    //                              new ToDoRepository(dc => new ToDoRepository(dc))));
    public TodoPresenter(Func<DataContext> dataContextFactory, 
                         Func<DataContext, ITodoService> serviceFactory)
    {
        this.dataContextFactory = dataContextFactory;
        this.serviceFactory = serviceFactory;
    }

    public void Save()
    {
        using (DataContext dataContext = this.dataContextFactory())
        {
            ITodoService service = serviceFactory(dataContext);
            // ...
            //service.Save(..);
            //dataContext.SubmitChanges();           
        }

    }
}

更新

服务还需要一个工厂来获取存储库

代码语言:javascript
复制
public TodoService(DataContext dataContext, 
         Func<DataContext, IRepository<Todo> todoRepository){...}

与Service和presenter的集成测试如下所示

代码语言:javascript
复制
  var toDoRepository = new Mock<..>(..);
  var datacontext= new Mock<..>(..);
  var presenter = new TodoPresenter(dc => datacontext, 
                  dc => new TodoService(dc, dc2 => toDoRepository ));

演示者的unitest开始如下所示

代码语言:javascript
复制
  var TodoService= new Mock<..>(..);
  var datacontext= new Mock<..>(..);
  var presenter = new TodoPresenter(dc => datacontext, 
                  dc => TodoService);
票数 2
EN

Stack Overflow用户

发布于 2011-03-03 03:58:54

我会将数据上下文包装在UnitOfWork中。并为每个调用/会话创建一个工作单元。

票数 0
EN

Stack Overflow用户

发布于 2011-03-03 12:40:42

您是否尝试过在to服务中创建datacontext?

代码语言:javascript
复制
public interface IRepository<T> where T : class
{
    IEnumerable<T> Find(Expression<Func<T, bool>> where);
    T Single(Expression<Func<T, bool>> where);
    void Save(T item);
    void SubmitChanges();
}

public class Repository<T> : IRepository<T> where T : class
{
    public void Save(T item)
    {
    }

    public void SubmitChanges()
    {
    }
}

// TodoService将拥有它的本地数据上下文

代码语言:javascript
复制
public class TodoService :IDisposable
{
   DataContext dataContext;
   IRepository<Todo> _todoRepository;
   public TodoService()
   {
       dataContext = DataContextFactory.GetNewContextForDatabase1();
       _todoRepository = new Repository<Todo>(dataContext);
   }

   public void Dispose()
   {
       dataContext.Dispose();
   }

   void Save(Todo item)
   {
       _todoRepository.Save(item);
   }

   void SubmitChanges()
   {
       _todoRepository.SubmitChanges();
   }
}

// presenter

代码语言:javascript
复制
class TodoPresenter
{
    public void Save()
    {
       using (TodoService service = new TodoService())
       {
           Todo item = null;
           // ...
           service.Save(item);
           service.SubmitChanges();           
       }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5171779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档