Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Onion Architecture- Entity Framework Code First Models DataAnnotations

I am developing a ASP.NET MVC Project following the Onion Architecture. I have added the Models inside my Core Project and these Models will be referred as the POCO classes for the Entity Framework Models in the Infrastructure Project.

My question is how can I add Data Annotations Which depends on the Entity Framework?

Can I make the Core Models as Interfaces and inherit it in the Infrastructure Projects and do real Implementation?

like image 236
Saanch Avatar asked Jun 05 '13 16:06

Saanch


People also ask

What is System ComponentModel DataAnnotations?

DisplayAttribute Class (System. ComponentModel. DataAnnotations) Provides a general-purpose attribute that lets you specify localizable strings for types and members of entity partial classes.

Is onion architecture DDD?

Onion is an architectural pattern for a system, whereas DDD is a way to design a subset of the objects in the system. The two can exist without eachother, so neither is a subset of the other. If you were to use them together - then as a whole the part that is designed using DDD would be a subset of the entire system.

Is MVC onion architecture?

In essence, MVC solves the separation of concern issue but the tight coupling issue still remains. On the other hand, Onion Architecture addresses both the separation of concern and tight coupling issues.

Which of the following layers are part of onion architecture?

Key tenets of Onion Architecture:Inner layers define interfaces. Outer layers implement interfaces. Direction of coupling is toward the center. All application core code can be compiled and run separate from infrastructure.


2 Answers

You don't need to create Core Models as Interfaces if you switch from Data Annotations the Fluent API.

Here's an example.

The Entity1 object is a core layer domain object:

namespace MyApp.Core.Model
{
  public class Entity1
  {
    public short Id { get; set; }
    public string ExternalCode { get; set; }
    public byte Status { get; set; }
  }
}

In the infrastructure layer, create an Entity1Mapping class where you'll do what you'd have done using Data Annotation, but this time, with the Fluent API instead:

using System.Data.Entity.ModelConfiguration;

namespace MyApp.Infrasrtucture.Data.Configuration
{
  internal class Entity1Mapping : EntityTypeConfiguration<Core.Model.Entity1>
  {
     internal Entity1Mapping()
     {
       HasKey(g => g.Id);
       Property(g => g.Id).IsRequired();

       Property(g => g.ExternalCode)
           .IsRequired()
           .HasMaxLength(100)
           .IsVariableLength()
           .IsUnicode(false);

       Property(g => g.Status).HasColumnName("EntityStatus").IsRequired();
     }
  }
}

Last thing you have to do, is adding the mapping in the modelBuilder of your context:

using System.Data.Entity;

namespace MyApp.Infrastructure.Data
{
  public class MyContext : DbContext, IDbContext
  {
    public MyContext() : base("ConnectionStringMyContext")
    { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      Database.SetInitializer<MyContext>(null);
      modelBuilder.Configurations.Add(new Configuration.Entity1Mapping());
    }
  }
}

This is the IDBContext just in case:

public interface IDbContext
{
  DbSet<T> Set<T>() where T : class;
  DbEntityEntry<T> Entry<T>(T entity) where T : class;
  int SaveChanges();
  void Dispose();
}
like image 170
MaxSC Avatar answered Oct 27 '22 20:10

MaxSC


Using FluentAPI is a good a solution in my opinion.

It is worth noting though that System.Component.DataAnnotations does not rely on EntityFramework - so you can use DataAnnotations in your core project and still be agnostic on your particular persistance mechanism.

like image 26
JTech Avatar answered Oct 27 '22 20:10

JTech