У меня есть MyWizardDto
, который я использую для перемещения объектов Dto между различными слоями. Объектами Dto может быть любое количество объектов. MyWizardDto
используется в MyWizardAppService
для вставки записей для каждого объекта в базу данных. В MyWizardAppService
я заранее знал бы супер набор репозиториев, которые могут потребоваться, в настоящее время я добавил два для демонстрационных целей, но они могут увеличиться, и если какой-либо объект Dto равен нулю, нам не нужно отображать или вызывать его метод репозитория для взаимодействия с базой данных.
В методе MyWizardAppService.CreateOrUpdate
я могу подключить несколько операторов if / else, чтобы сначала сопоставить каждый Dto (ClientDto, ContactDto)
его соответствующей сущности (Client, Contact)
, используя Automapper
, а затем вызвать соответствующий репозиторий (_clientRepository, _contactRepository)
для добавления / обновления записи в базе данных. Однако мне интересно, могу ли я использовать рефлексию или какой-либо другой метод, чтобы избежать множественных операторов if / else, так как количество сущностей может увеличиться. Я всегда буду знать надмножество заранее, поэтому все соответствующие репозитории будут внедрены так же, как и текущие два репозитория.
Можно ли изменить мой MyWizardAppService.CreateOrUpdate
метод для достижения sh моей цели без использования нескольких операторов if / else? Я придерживаюсь того же соглашения об именах, например, ClientDto, Client and _clientRepository
, поэтому я не знаю, может ли это быть полезным для использования в качестве практического правила.
public class MyWizardDto
{
public ClientDto client { get; set; }
public ContactDto contact { get; set; }
}
public class ClientDto
{
public string Forename { get; set; }
public string Surname { get; set; }
public DateTime? DateOfBirth { get; set; }
}
public class ContactDto
{
public string Street { get; set; }
public string City{ get; set; }
}
public class Client
{
public string Forename { get; set; }
public string Surname { get; set; }
public DateTime? DateOfBirth { get; set; }
}
public class Contact
{
public string Street { get; set; }
public string City{ get; set; }
}
public interface IMyWizardAppService
{
Task<ResponseOutputDto> CreateOrUpdate(MyWizardDto myWizardDto);
}
public class ResponseOutputDto
{
public bool IsSuccess { get; set; }
public string Message { get; set; }
}
public class MyWizardAppService
{
private readonly IRepository<Client> _clientRepository;
private readonly IRepository<Contact> _contactRepository;
// there can be more repository entities
private ResponseOutputDto responseOutputDto;
public MyWizardAppService(
IRepository<Client> clientRepository,
IRepository<Contact> contactRepository)
{
_clientRepository = clientRepository;
_contactRepository = contactRepository;
responseOutputDto = new ResponseOutputDto();
}
public async Task<ResponseOutputDto> CreateOrUpdate(MyWizardDto myWizardDto)
{
PropertyInfo[] properties = myWizardDto.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
string temp = property.Name;
// to check if property is dto object and is not null
// if not null then map dto to its corresponding object e.g ClientDto to Client,
//I am using AutoMapper e.g ObjectMapper.Map<Client>(myWizardDto.client);
// now call corresponding entities repository e.g if ClientDto then call
// _clientRepository's insert.
}
//if no error return success
responseOutputDto.IsSuccess = true;
return responseOutputDto;
}
}
В соответствии с предложением @Unknown, я изменил MyWizardAppService, как показано ниже, но теперь я получаю ошибку времени компиляции: Client / IRepository - это тип, который недопустим в данном контексте
public class MyWizardAppService
{
private readonly IRepository<Client> _clientRepository;
private readonly IRepository<Contact> _contactRepository;
private Dictionary<Type, IRepository> _repositoryPairs;
// there can be more repository entities
private ResponseOutputDto responseOutputDto;
public MyWizardAppService(
IRepository<Client> clientRepository,
IRepository<Contact> contactRepository)
{
_clientRepository = clientRepository;
_contactRepository = contactRepository;
responseOutputDto = new ResponseOutputDto();
_repositoryPairs = new Dictionary<Type, IRepository>();
//GET ERROR ON FOLLOWING LINE
_repositoryPairs.Add(<Client>, IRepository<Client>);
}
public async Task<ResponseOutputDto> CreateOrUpdate(MyWizardDto myWizardDto)
{
PropertyInfo[] properties = myWizardDto.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
string temp = property.Name;
// to check if property is dto object and is not null
// if not null then map dto to its corresponding object e.g ClientDto to Client,
//I am using AutoMapper e.g ObjectMapper.Map<Client>(myWizardDto.client);
// now call corresponding entities repository e.g if ClientDto then call
// _clientRepository's insert.
}
//if no error return success
responseOutputDto.IsSuccess = true;
return responseOutputDto;
}
}
Обновление 2 Теперь я получаю сообщение об ошибке на TryGet, которое говорит Disctionary делает не содержит определения для TryGet.
public class MyWizardAppService
{
private readonly IRepository<Client> _clientRepository;
private readonly IRepository<Contact> _contactRepository;
private Dictionary<Type, IRepository> _repositoryPairs;
// there can be more repository entities
private ResponseOutputDto responseOutputDto;
public MyWizardAppService(
IRepository<Client> clientRepository,
IRepository<Contact> contactRepository)
{
_clientRepository = clientRepository;
_contactRepository = contactRepository;
responseOutputDto = new ResponseOutputDto();
_repositoryPairs = new Dictionary<Type, IRepository>();
_repositoryPairs.Add(typeOf(Client), _clientRepository);
}
public async Task<ResponseOutputDto> CreateOrUpdate(MyWizardDto myWizardDto)
{
PropertyInfo[] properties = myWizardDto.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
string temp = property.Name;
IRepository repo;
if (_repositoryPairs.TryGet(property.GetType(), out repo))
{
//call insert here some how
}
// to check if property is dto object and is not null
// if not null then map dto to its corresponding object e.g ClientDto to Client,
//I am using AutoMapper e.g ObjectMapper.Map<Client>(myWizardDto.client);
// now call corresponding entities repository e.g if ClientDto then call
// _clientRepository's insert.
}
//if no error return success
responseOutputDto.IsSuccess = true;
return responseOutputDto;
}
}