How to use interfaces like Dbset’s in the C#Entity Framework

Asked

Viewed 113 times

3

Hello, I’m making a solution where my entire business layer is in a separate project and in this project I created the layer relational structure from interfaces as shown in the example below:

// interfaces de definição de características 
public interface IHasIndex {
    int Id { get; set; }
}
...
// estrutura da aplicação
public interface IEmpresa: IHasIndex {
    string RazaoSocial { get; set; }
}
public interface IUsuario: IHasIndex {
    string Login { get; set; }
    string Senha { get; set; }
    IEmpresa Empresa { get; set; }
}
...

The intention is to take advantage of the multiple inheritance that the interfaces allow me and to standardize the nomenclature of the fields as well as to allow the use of the interfaces of defining characteristics as specific selectors, generalizing the application, reducing code, standardizing methods, etc...

My problem is time to generate the models of this solution. I am working with Entity Framework Core and even if it allows the use of interfaces in defining DbSet<T> (as shown at that link) I intend to use Model classes that implement the application logic interfaces, as shown below:

[Table("Empresa")]
public class EmpresaModel: IEmpresa {
    [Key]
    public int Id { get; set; }
    public string RazaoSocial { get; set; }
}
[Table("Usuario")]
public class UsuarioModel: IUsuario {
    [Key]
    public int Id { get; set; }
    public string Login { get; set; }
    public string Senha { get; set; }

    public int EmpresaId { get; set; } // FK para Empresa
    [ForeignKey("EmpresaId")]
    public EmpresaModel Empresa { get; set; }

}

When I set out to use EmpresaModel as the IEmpresa in class UsuarioModel, C# tells me that the interface has not been implemented. In my view, if EmpresaModel implements IEmpresa, then (theoretically) I could use the class instead of the interface. How to solve?

EDIT: To make the situation clearer based on what @Marconciliosouza said about multiple inheritance, I will expand the Iempresa interface with all the attributes and inheritances...

// interfaces de definição de características 
public interface IHasVisibility {
    bool Visivel { get; set; }
}
public interface IHasDefault {
    bool Padrao { get; set; }
}
public interface IHasCreationEvent {
    bool CriadoEm { get; set; }
}

// estrutura da aplicação
public interface IPessoaJuridica {
    string RazaoSocial { get; set; }
    string NomeFantasia { get; set; }
    string Cnpj { get; set; }
    string InscricaoEstadual { get; set; }
    string InscricaoMunicipal { get; set; }
}
public interface IPessoaFisica {
    string Nome { get; set; }
    string Sobrenome { get; set; }
    string Cpf { get; set; }
    string Rg { get; set; }
}
public interface IEndereco : IHasIndex {
    string Logradouro { get; set; }
    string Numero { get; set; }
    string Complemento { get; set; }
    string Bairro { get; set; }
    string Localidade { get; set; }
    string Uf { get; set; }
    string Pais { get; set; }
    string Cep { get; set; }
}
public interface IContato: IHasIndex {
    string Tipo { get; set; }
    string Descricao { get; set; }
    string Observacao { get; set; }
}
public interface IContatoWithDefault: IContato {
}
public interface IEmpresa : IHasIndex, IHasDefault, IHasCreationEvent, IHasVisibility {
    IPessoaJuridica PessoaJuridica { get; set; }
    IPessoaFisica PessoaFisica { get; set; }
    IEndereco Endereco { get; set;}
    ICollection<IContatoWithDefault> Contatos { get; set; }
}
  • 1

    recently I tried to do something similar, but I didn’t devote much time to it. My solution was to pass the class type in the statement... public interface Usuario<TEmpresa> ... public TEmpresa Empresa {get;set;}; for me attended without problems, but if someone has a better solution, update my code =]

  • 1

    It does not seem to me the best use of interfaces and in case as all entities will have a property int Id, why not simply create a class BaseModel with and that will be inherited by the others?

  • @Rovannlinhalis I also thought about it, the problem is that with it begins to turn gambiarra... imagine if I have an interface that has many interfaces as properties, looks as much of type that should be passed to solve this...

  • 1

    yes, as I said, in my case it was no problem. I wait if another member will have a better / suitable solution. vlw

  • @Leandroangelo the problem of inheriting a BaseModel is that I could not benefit from multiple inheritances. Using the above approach, I may have "N" specific properties, e.g.: IHasState (state control), IHasVisibility (occult), IStartAndEnd (requires to have start and end dates), etc...

  • @Leandroangelo and I can still standardize the nomenclature of all fields as I want. The advantage of this is that you have a much more logical, simple and intuitive structure

  • 1

    @Rovannlinhalis I even found a way to do, (the one I put in the project) but the description itself in the stack is very "by the coconuts", hence I’m looking for a more intelligent and optimized... if I find I put and you can use ai =D

  • 1

    just one observation... to declare the interfaces, I used . net standart, so I was able to use them in . net core implementing an api, and in . net framework, implementing a winforms application.

  • 1

    If you replace the property that uses your Empresamodel public EmpresaModel Empresa { get; set; } by a property with the Iempresa interface public IEmpresa Empresa { get; set; } would not answer?

  • 1

    @Rovannlinhalis I am also using this, in my Solution I have 3 projects (so far) being Lib (.NET Standard), Api (.NET Core), Mobile (Xamarin) but using this methodology I can have "n" that will not make a difference and all will have the same logic

  • @Renan is exactly what I’m having trouble with... Efcore can’t implement non-bootable structures so I have to tinker with my implementation understand?

  • 1

    this is further used for abstract class https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/abstract

  • @Marconciliosouza if I use abstract classes I won’t be able to take advantage of multiple heritages... for this reason I can’t use

  • 1

    you won’t be able to inherit two classes, but do what you did with the interfaces you can

  • @Marconciliosouza in C# the only way to make multiple inheritance is thus Kra...

  • 1

    and where in your example code you are using multiple inheritance ? do not see you use EmpresaModel: IEmpresa , IUsuario or UsuarioModel: IUsuario ,IEmpresa . you are inheriting only one interface you already inherit from another interface. see this https://answall.com/a/3602/43340

  • The code is an example and I will use inheritance in this project. I will change it so that you have inheritance to better understand...

Show 12 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.