Вы не должны иметь реализацию, непосредственно связанную с вашей собственностью. Причина в том, что сущность - это представление ваших данных, а сущности не волнует, как элемент хранится или создается. Просто представление вашего бизнес-объекта.
Другая проблема заключается в том, что вы нарушаете более распространенную практику следования доменному дизайну, согласно определению Мартина Фаулера и Эванса. Одним из самых серьезных нарушений может быть тот факт, что вы навязываете логику в свойстве, если вы вызываете свойство, то вы автоматически попадаете в базу данных.
Как обозначено авторами 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();
}
Итак, мы создали некоторую абстракцию, мы создали наш контейнер, у нас есть четкие контракты с соответствующими реализациями. Поэтому, если кто-то хочет использовать то, что вы создали, это будет выглядеть следующим образом:
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);
}
}
Поэтому, когда они взаимодействуют с реализацией вашего сервиса, это создаст ясность, но также обеспечит ясный, лаконичный и выразительный поток кода. Разработчик может ясно видеть, что происходит в реализации сервиса, но совершенно не замечает, как происходит реализация данных.
Я не добавил обработки ошибок или нулевых проверок, но, надеюсь, это поможет вам.