jeudi 6 mai 2021

Dependency Injection conceptual problem: where to instantiate new object to save to the db?

I am working on a small toy program to learn some basics about DI and IoC on .Net Core 3.1.

I have several questions, mostly consisting on where and when to perform certain actions.

I have created the following architecture for my project:

A DAL layer, Database First, that has the db entities, context, and extensions for the entities, along with a generic implementation of a repository:

public class Repository<T> : IRepository<T> where T : BaseEntity
{
    private readonly DbContext context;
    private DbSet<T> entities;
    string errorMessage = string.Empty;

    public Repository(DbContext context)
    {
        this.context = context;
        entities = context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return entities.AsEnumerable();
    }
    public T Get(Guid id)
    {
        //return entities.SingleOrDefault(s => s. == id);
        return null;
    }
    public void Insert(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Add(entity);
            context.SaveChanges();
        }
        catch (Exception e)
        {
            //log ERROR
        }
    }
    public void Update(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            context.SaveChanges();
        }
        catch (Exception e)
        {

            //log error
        }
    }
    public void Delete(T entity)
    {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Remove(entity);
            context.SaveChanges();
        }
        catch (Exception e)
        {

            //log error
        }
    }

    public void SoftDelete(T entity) {
        try
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            //context.SoftDelete(entity as EntityEntry);
            //context.SaveChanges();
        }
        catch (Exception e)
        {

            //log error
        }
    }
}

I also have a Services and a WebAPI layer, with a monolithic architecture (all services are in the same package, all API requests go against a certain service class within said package).

All real business logic is whitin the Services layer, with the exception of some utilities, exceptions and generic functions in a Commons layer.

Also, I have a "Domain" layer, in which I have the API models. These models are the ones that I use when recieving a POST request, for example.

My biggest question right now is: where/when and how do I create the new instance of the DB entities (from the API Models)?

Right now I have this in my Services layer:

public class AnonymousLoginService : IAnonymousLoginService
{
    public IRepository<AnonymousLogin> _repository { get; set; }

    public AnonymousLoginService(IRepository<AnonymousLogin> repository)
    {
        _repository = repository;
    }


    public void SaveNewLogin(AnonymousLoginModel newEntry)
    {
        //HOW TO DO THIS CORRECTLY?
        var itemToSave = new AnonymousLogin();
        itemToSave.Username = newEntry.Username;
        itemToSave.Id = Guid.NewGuid();
        itemToSave.IsDeleted = false;
        itemToSave.LoginDate = DateTimeOffset.Now.ToString();
        itemToSave.Ipaddress = newEntry.Ipaddress;

        ValidationResult validation = (ValidationResult)itemToSave.ValidateSelf<IAnonymousLogin>();

        if (validation.IsValid)
        {
            _repository.Insert(itemToSave);
        }
        else
            throw new Exception("OMG");
    }


}

AnonymousLoginModel is the object that comes from the WEB Api (the object created from the body of the POST reques) and AnonymousLogin is the entity to be saved to the DB. As you can see, I am creating a new instance of the AnonymousLogin object, but that goes directly against DI. Where should I create the new entry? Is this implementation correct? Should the services layer know both the Web Api models AND the DB objects?

Also, I am worried about the concept of the entire Domain Layer. It it okay that it is in a separate package/project? Should all of those models be inside of the Web Api itself? None of the above?

I would really appreciate the help, since it's very hard to get straigth answers (most information online are examples that don't really apply to this particular scenario). Thanks in advance!

Aucun commentaire:

Enregistrer un commentaire