C# 从Mongo读取数据时发送IRepository模型依赖项
在我的应用程序中,我使用Autofac ContainerBuilder注册我的存储库 我还有一个CustomerModel类,它表示MongoDB集合。它还对其他域模型具有正向依赖性:C# 从Mongo读取数据时发送IRepository模型依赖项,c#,mongodb,dependency-injection,domain-driven-design,autofac,C#,Mongodb,Dependency Injection,Domain Driven Design,Autofac,在我的应用程序中,我使用Autofac ContainerBuilder注册我的存储库 我还有一个CustomerModel类,它表示MongoDB集合。它还对其他域模型具有正向依赖性: public class CustomerModel { private readonly IRepository<OrderModel> _ordeRepository; public CustomerModel(IRepository<OrderModel> ord
public class CustomerModel
{
private readonly IRepository<OrderModel> _ordeRepository;
public CustomerModel(IRepository<OrderModel> ordeRepository)
{
_ordeRepository = ordeRepository;
}
[BsonId]
public ObjectId Id;
public string Email;
...
public List<OrderModel> Orders
{
get { return _ordeRepository.List(x => x.CustomerId == Id); }
}
}
公共类CustomerModel
{
私有只读存储库_ordeRepository;
公共客户模型(IRepository OrderDepository)
{
_ordeRepository=ordeRepository;
}
[BsonId]
公共对象Id;
公共字符串电子邮件;
...
公开名单命令
{
获取{return _ordeRepository.List(x=>x.CustomerId==Id);}
}
}
从Mongo读取数据时,如何注入IRepository依赖关系
public interface IRepository<TEntity>
{
IList<TEntity> List(Expression<Func<TEntity, bool>> expression);
}
public class MongoRepository<TEntity> : IRepository<TEntity>
{
public IList<TEntity> List(Expression<Func<TEntity, bool>> expression)
{
IMongoCollection<TEntity> collection = ...;
return collection.FindSync(expression).ToList();
}
}
公共接口IRepository
{
IList列表(表达式);
}
公共类MongoRepository:IRepository
{
公共IList列表(表达式)
{
IMongoCollection集合=。。。;
return collection.FindSync(expression.ToList();
}
}
您不应该让实现与您的属性直接关联。原因是,实体是数据的表示,实体不关心项目的存储或创建方式。只是业务对象的表示
另一个问题是,根据Martin Fowler和Evans的定义,您违反了遵循领域驱动设计的更常见实践。最大的违规之一是,您在一个属性中强制使用逻辑,如果您调用该属性,则会自动访问数据库
正如C#深度作者所指出的:
<>对于你所写的每种类型,你应该考虑它的接口
世界其他地区(包括同一程序集中的类)。这
是它对它所提供的东西的描述,它的外在角色。
实现不应该是描述的一部分,也不应该是描述的一部分
绝对是的。(这就是为什么我更喜欢构图而不是继承,
选择有意义的地方——继承通常会暴露或限制
可能的实现。)
物业传达了“我将为客户提供价值”的理念
“这不是一个实现概念,
这是一个界面概念。另一方面,一个字段进行通信
实现——它说“这个类型代表这个类型中的一个值
非常具体的方式”。没有封装,这是裸存储
格式。这是字段不属于接口的部分原因-
他们不属于那里,因为他们谈论如何取得成就
而不是所取得的成就
我非常同意,很多时候,字段实际上可以被使用
在应用程序的生命周期中没有问题。只是不清楚
这些时间都是预先设定的,但它仍然违反了设计
不公开实现的原则
在遵循设计原则的同时处理实现可能更适合以下方法和/或体系结构风格。请记住,模式不是饼干切割器。他们为特定的原因解决特定的问题,他们引入自身的复杂性和问题。您必须根据您的应用权衡解决方案的优点
// Repositories:
public interface ICustomerRepository : IDisposable
{
IEnumerable<CustomerModel> RetrieveAllCustomers();
CustomerModel RetrieveCustomerWithOrders(int id);
}
// Context:
public class CustomerContext : ICustomerRepository
{
private bool disposed = false;
private readonly IDbConnection dbConnection;
public CustomerContext(IConfiguration configuration) => dbConnection = configuration.GetConnectionString("dbConnection");
public IEnumerable<CustomerModel> RetrieveAllCustomers() => dbConnection.Query<CustomerModel>(query);
public CustomerModel RetrieveCustomerWithOrders(int id) => dbConnection.Query<CustomerModel, OrderModel, CustomerModel>(query, (customer, order) =>
{
customer.Orders = order;
return customer;
}, new { CustomerId = id });
public virtual bool Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
dbConnection.Dispose();
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~CustomerContext() => Dispose(true);
}
// Factory:
public class CustomerFactory : ICustomerFactory
{
private readonly IConfiguration configuration;
public CustomerFactory(IConfiguration configuration) => this.configuration = configuration;
public ICustomerRepository InstantiateCustomer() => new CustomerContext(configuration);
}
public interface ICustomerFactory
{
ICustomerRepository InstantiateCustomer();
}
//存储库:
公共接口ICCustomerRepository:IDisposable
{
IEnumerable RetrieveAllCustomers();
CustomerModel RetrieveCustomerWithOrders(int id);
}
//背景:
公共类CustomerContext:ICCustomerRepository
{
私有布尔=假;
专用只读IDbConnection dbConnection;
公共CustomerContext(IConfiguration配置)=>dbConnection=configuration.GetConnectionString(“dbConnection”);
public IEnumerable RetrieveAllCustomers()=>dbConnection.Query(查询);
公共CustomerModel RetrieveCustomerWithOrders(int id)=>dbConnection.Query(查询,(客户,订单)=>
{
客户订单=订单;
退货客户;
},新的{CustomerId=id});
公共虚拟bool Dispose(bool disposing)
{
如果(!已处置)
{
如果(处置)
dbConnection.Dispose();
这是真的;
}
}
公共空间处置()
{
处置(真实);
总干事(本);
}
~CustomerContext()=>Dispose(true);
}
//工厂:
公共类CustomerFactory:ICCustomerFactory
{
专用只读IConfiguration配置;
公共CustomerFactory(IConfiguration配置)=>this.configuration=configuration;
公共ICCustomerRepository instanceCustomer()=>新的CustomerContext(配置);
}
公共接口ICustomerFactory
{
icCustomerRepository实例化ecustomer();
}
因此,我们创建了一些抽象,我们构建了我们的容器,我们与适当的实现有明确的契约。因此,如果有人现在要使用您构建的内容,它将如下所示:
public class CustomerService
{
private readonly ICustomerFactory customerFactory;
private readonly IConfiguration configuration;
public CustomerService(ICustomerFactory customerFactory, IConfiguration configuration)
{
this.customerFactory = customerFactory;
this.configuration = configuration;
}
public IEnumerable<CustomerModel> GetAllCustomers()
{
using(var customerContext = customerFactory.InstantiateCustomer(configuration))
return customerContext.RetrieveAllCustomers();
}
public CustomerModel GetCustomerOrders(CustomerModel customer)
{
using(var customerContext = customerFactory.InstantiateCustomer(configuration))
return customerContext.RetrieveCustomerWithOrders(customer.Id);
}
}
公共类客户服务
{
私有只读ICCustomerFactory customerFactory;
专用只读IConfiguration配置;
公共CustomerService(ICCustomerFactory customerFactory,IConfiguration配置)
{
this.customerFactory=customerFactory;
this.configuration=配置;
}
公共IEnumerable GetAllCustomers()
{
使用(var customerContext=customerFactory.instanceCustomer(配置))
返回customerContext.RetrieveAllCustomers();
}
公共CustomerModel GetCustomerOrders(CustomerModel客户)
{
使用(var customerContext=customerFactory.instanceCustomer(配置))
返回customerContext.RetrieveCustomerWithOrders(customer.Id);
}
}
因此,当它们与您的服务实现交互时,它将创建清晰性,但也将允许清晰、简洁和表达性的代码流。实现者可以清楚地看到服务imp中发生了什么