使用依赖注入WCF服务方法和EF

时间:2014-01-21 11:21:34

标签: c# wcf entity-framework mocking unity-container

我试图让Unity依赖注入与使用Entity Framework的WCF服务一起工作,但我对上下文和存储库的使用感到困惑。

我设计它的方法是拥有许多存储库类,例如UserRepository,MessageRepository,LocationRepository,每个存储库都接受一个EF DbContext对象作为构造函数参数。这使我可以在上下文级别控制工作单元,方法是调用context.Save()或rollback等来控制存储库之间的事务处理。

我所处理的混乱是我不确定如何在依赖注入中表示这一点。我想有两个场景

a)当通过WCF方法实例化WCF服务时,我希望它使用我创建的DbContext类并创建存储库对象,传入将连接到Entity Framework数据库的已创建的DbContext。

b)当从单独的测试项目测试WCF服务方法时,我想模拟存储库对象以返回模拟数据。

如果我只是使用存储库类,这将相对简单,因为在每个WCF服务方法中我可以调用Container.Resolve()然后我可以使用Unity WCF工厂来设置WCF实例化的具体类型,并手动在我的测试项目中为模拟类型配置Unity容器。

但困难在于我的存储库需要一个DbContext类作为构造函数参数传入,该参数将在存储库的生命周期内存活,并且我还需要能够在我的服务方法中引用它,例如

public bool CreateUser(DbUser user)
{
    try
    {
        using (var context = new MyDbContext())
        {
            var repository = new UserDataRepository(context);

            user.GenerateUserLight();
            user.GenerateUserProfileLight();

            var result = repository.InsertItem(user);
            repository.Save();

            return result;
        }
    }
    catch (Exception ex)
    {
        return false;
    }
}

如何调整上述方法以使用Unity Dependency注入,以便我可以为测试项目模拟它?

1 个答案:

答案 0 :(得分:0)

据我所知,这里的问题是您应该在存储库中创建上下文,事实上您实际上是在新建服务中的上下文然后将其传递到您的存储库中是一些代码气味

为什么不让存储库处理DbContext?这样,您就不会首先将您的存储库耦合到Entity Framework。

服务应该只依赖于IUserRepository接口..而不是具体的实现。

private readonly IUserRepository _userRepository;

public MyService(IUserRepository userRepository)   
{
    this._userRepository = userRepository;
}
public bool CreateUser(DbUser user)
{
    try
    {
            user.GenerateUserLight();
            user.GenerateUserProfileLight();

            var result = this._userRepository.InsertItem(user);
            this._userRepository.Save();

            return result;
    }
    catch (Exception ex)
    {
        return false;
    }
}

用户存储库会在其构造函数中接受DbContext,您还需要在DI容器中注册上下文,以便DI在注入服务时可以构造UserRepository。

public class UserRepository : IUserRepository
{
    private readonly MyDbContext context;

    public UserRepository(MyDbContext context)
    {
        this.context = context;
    }
}

然后你可以通过构造函数将“UserRepository”注入服务。

这也使您能够创建完全不需要上下文的Mock存储库类型,只需为存储库创建一个接口。