C# 解耦我的ObjectContext

C# 解耦我的ObjectContext,c#,dependency-injection,ninject,inversion-of-control,C#,Dependency Injection,Ninject,Inversion Of Control,我有一个ASP.NET MVC应用程序,它让我的控制器调用命令调用程序来执行CRUD操作。命令处理程序位于我的域层程序集中。其中一个命令处理程序使用以下代码保存记录: public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand> { public void Handle(SaveTransactionCommand command) { usin

我有一个ASP.NET MVC应用程序,它让我的控制器调用命令调用程序来执行CRUD操作。命令处理程序位于我的域层程序集中。其中一个命令处理程序使用以下代码保存记录:

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand>
{
    public void Handle(SaveTransactionCommand command)
    {
        using (GiftCardEntities db = new GiftCardEntities())
        {
            db.Transactions.AddObject(new Transaction
            {
                GiftCardId = command.GiftCardId, 
                TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
                Amount = command.Amount,
                TransactionDate = DateTime.Now
            });
            db.SaveChanges();
        }
    }
}
公共类SaveTransactionCommandHandler:ICommandHandler
{
公共无效句柄(SaveTransactionCommand)
{
使用(giftcardenties db=new giftcardenties())
{
db.Transactions.AddObject(新事务
{
GiftCardId=command.GiftCardId,
TransactionTypeId=Convert.ToInt32(命令.TransactionTypeId),
Amount=command.Amount,
TransactionDate=DateTime.Now
});
db.SaveChanges();
}
}
}

但是,正如您所看到的,我的处理程序依赖于ObjectContext(EF)。我正在用Ninject学习依赖注入。现在我知道我的处理程序(域对象)不应该依赖于任何数据层对象。但在我的例子中,处理程序依赖于作为ObjectContext的GiftCardenties。如何更改处理程序,使其与ObjectContext解耦?

您应该使用存储库模式。存储库将抽象实际使用的数据访问技术。通过这种方式,您可以为不同的数据访问技术提供多个存储库实现,您可以在不更改业务层代码的情况下进行切换。 所以,您的处理程序看起来像

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand>
{
    readonly ITransactionRepository repository;

    public SaveTransactionCommandHandler(ITransactionRepository repository)
    {
          this.repository = repository;
    }
    public void Handle(SaveTransactionCommand command)
    {

            repository.Save(new Transaction
            {
                GiftCardId = command.GiftCardId, 
                TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
                Amount = command.Amount,
                TransactionDate = DateTime.Now
            });

    }
}  
公共类SaveTransactionCommandHandler:ICommandHandler
{
只读ITransactionRepository;
public SaveTransactionCommandHandler(ITransactionRepository存储库)
{
this.repository=存储库;
}
公共无效句柄(SaveTransactionCommand)
{
存储库。保存(新事务)
{
GiftCardId=command.GiftCardId,
TransactionTypeId=Convert.ToInt32(命令.TransactionTypeId),
Amount=command.Amount,
TransactionDate=DateTime.Now
});
}
}  

存储库实例将由DI容器注入到您的处理程序中,在您的情况下是ninject。

您应该使用存储库模式。存储库将抽象实际使用的数据访问技术。通过这种方式,您可以为不同的数据访问技术提供多个存储库实现,您可以在不更改业务层代码的情况下进行切换。 所以,您的处理程序看起来像

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand>
{
    readonly ITransactionRepository repository;

    public SaveTransactionCommandHandler(ITransactionRepository repository)
    {
          this.repository = repository;
    }
    public void Handle(SaveTransactionCommand command)
    {

            repository.Save(new Transaction
            {
                GiftCardId = command.GiftCardId, 
                TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
                Amount = command.Amount,
                TransactionDate = DateTime.Now
            });

    }
}  
公共类SaveTransactionCommandHandler:ICommandHandler
{
只读ITransactionRepository;
public SaveTransactionCommandHandler(ITransactionRepository存储库)
{
this.repository=存储库;
}
公共无效句柄(SaveTransactionCommand)
{
存储库。保存(新事务)
{
GiftCardId=command.GiftCardId,
TransactionTypeId=Convert.ToInt32(命令.TransactionTypeId),
Amount=command.Amount,
TransactionDate=DateTime.Now
});
}
}  

存储库实例将由DI容器注入到您的处理程序中,在您的情况下是ninject。

您应该使用存储库模式。存储库将抽象实际使用的数据访问技术。通过这种方式,您可以为不同的数据访问技术提供多个存储库实现,您可以在不更改业务层代码的情况下进行切换。 所以,您的处理程序看起来像

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand>
{
    readonly ITransactionRepository repository;

    public SaveTransactionCommandHandler(ITransactionRepository repository)
    {
          this.repository = repository;
    }
    public void Handle(SaveTransactionCommand command)
    {

            repository.Save(new Transaction
            {
                GiftCardId = command.GiftCardId, 
                TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
                Amount = command.Amount,
                TransactionDate = DateTime.Now
            });

    }
}  
公共类SaveTransactionCommandHandler:ICommandHandler
{
只读ITransactionRepository;
public SaveTransactionCommandHandler(ITransactionRepository存储库)
{
this.repository=存储库;
}
公共无效句柄(SaveTransactionCommand)
{
存储库。保存(新事务)
{
GiftCardId=command.GiftCardId,
TransactionTypeId=Convert.ToInt32(命令.TransactionTypeId),
Amount=command.Amount,
TransactionDate=DateTime.Now
});
}
}  

存储库实例将由DI容器注入到您的处理程序中,在您的情况下是ninject。

您应该使用存储库模式。存储库将抽象实际使用的数据访问技术。通过这种方式,您可以为不同的数据访问技术提供多个存储库实现,您可以在不更改业务层代码的情况下进行切换。 所以,您的处理程序看起来像

public class SaveTransactionCommandHandler : ICommandHandler<SaveTransactionCommand>
{
    readonly ITransactionRepository repository;

    public SaveTransactionCommandHandler(ITransactionRepository repository)
    {
          this.repository = repository;
    }
    public void Handle(SaveTransactionCommand command)
    {

            repository.Save(new Transaction
            {
                GiftCardId = command.GiftCardId, 
                TransactionTypeId = Convert.ToInt32(command.TransactionTypeId), 
                Amount = command.Amount,
                TransactionDate = DateTime.Now
            });

    }
}  
公共类SaveTransactionCommandHandler:ICommandHandler
{
只读ITransactionRepository;
public SaveTransactionCommandHandler(ITransactionRepository存储库)
{
this.repository=存储库;
}
公共无效句柄(SaveTransactionCommand)
{
存储库。保存(新事务)
{
GiftCardId=command.GiftCardId,
TransactionTypeId=Convert.ToInt32(命令.TransactionTypeId),
Amount=command.Amount,
TransactionDate=DateTime.Now
});
}
}  

存储库实例将由DI容器注入到您的处理程序中,在您的情况下是ninject。

我同意应该注入内容/存储库,而不是实例化。但是,添加额外的存储库抽象层有什么好处?如果您永远不需要它b/c,那么就不会“同时”使用多种数据访问技术,您只会白白增加复杂性和成本。如果您要切换技术,它们要么相似,因此即使没有抽象也很容易适应,要么不相似,在这种情况下,抽象只会给您一种错误的安全感(以及更多的工作和复杂性…)@tsvayer:我试着使用Repository模式,但现在我发现自己也有同样的问题,只是在我的TransactionRepository类中。我该怎么办