Onion Architecture- Entity Framework Code First Models DataAnnotations
Asked Answered
S

2

5

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?

Sequestered answered 5/6, 2013 at 16:25 Comment(0)
C
15

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();
}
Cloche answered 6/6, 2013 at 11:36 Comment(3)
Looks like a good solution. I haven't marked this as answer, just to see if any other interesting approach are coming.Sequestered
@max I liked this solution, but I have a question about the Remote Attribute, how one would deal with it in this situation? Thanks.Piliform
Well you shouldn't use your domain model as viewmodel. The core layer domain entities are designed to manage your business, not what you will display to the user. So you will certainly have other presentation entities (viewmodels) where you'll be able to put your Remote attribute as you're used to (it will be up to the model builder to map your domain objects to viewmodels)Cloche
C
1

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.

Capreolate answered 15/12, 2015 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.