Search code examples
c#entity-framework-coreentitydto

How do I use one method for multiple DTO?


I have an Address entity as follows:

public class Address
{
    public string? City { get; set; }
    public string? Country { get; set; }
    public string? Contact { get; set; }
    public string? Street1 { get; set; }
    public string? Street2 { get; set; }
    public string? State { get; set; }
    public string? Zip { get; set; }
}

According to the best practices, I use different DTOs for different parts of app according to the users' needs. Suppose that I have two DTOs from the Address entity as follows:

public class AddressDto1
    {
        public string? City { get; set; }
        public string? Country { get; set; }
        public string? Contact { get; set; }
        public string? Street1 { get; set; }
        public string? Street2 { get; set; }
        public string? State { get; set; }
        public string? Zip { get; set; }
    } 
public class AddressDto2
    { 
        [Requierd]
        public string Street1 { get; set; }
        [Requierd]
        public string Street2 { get; set; }
        public string? State { get; set; }
        public string? Zip { get; set; }
    }

User1 can see and create the Address by AddressDto1 field, and User2 can see and create the Address by AddressDto2 field.
I have a method in the service that inherit from an interface and I use AutoMapper to map the DTO to Entity.

public interface IAddressService
{
    public Task<AddressDto1> CreateAddressAsync(AddressDto1 AddressDto1);
}

public class AddressService:IAddressService
{
    public Task<AddressDto1> CreateAddressAsync(AddressDto1 addressDto1)
    {
        var newAddress = _mapper.Map<Address>(addressDto1);
        var addedAddress = await _dbContext.Addresses.AddAsync(newAddress);
        await _dbContext.SaveChangesAsync();
        return _mapper.Map<AddressDto1>(addedAddress.Entity);
    }
}

And it's mapping profile:

public MappingProfile()
    {
        CreateMap<AddressDto1, Address>().ReverseMap();
        CreateMap<AddressDto2, Address>().ReverseMap();
    }

I'd like to use CreateAddressAsync for any AddressDtos. What should be the best way to implement CreateAddressAsync method so that the AddressDto2 can be added to the bank with the same method?


Solution

  • You need to make you method generic so that you can call the service for both models

    public async Task<T> CreateAddressAsync<T>(T addressDto1)
        {
            var newAddress = _mapper.Map<T, Address>(T);
            var addedAddress = await _dbContext.Addresses.AddAsync(newAddress);
            await _dbContext.SaveChangesAsync();
            return _mapper.Map<Address, T>(addedAddress.Entity);
        }
    
    //calling service
    var address1= await _addressService.CreateAddressAsync<AddressDto>(model);
    

    You can have more control over input parameters by having a base model for address dto after you can add this where T: baseAddress

    Also you can make data layer generic by _dbContext.Set<TEntity>.