0
votes

I have SOA Layer architecture for C# application. I have defined Business/ Domain Entities in Business Access Layer 'Class Library Project'.... Data Entities in Data Access Layer 'Class Library Project' and Data Contract for Server side WCF is under WCF Service 'Class Library Project'

My Question is how and where I should map data entities to business entities in generic repository and unit of work pattern.

Business Entity

using System;
using System.Collections.Generic;
using System.Linq;

namespace App.Core.Entities
{
public class Member
{
    public int MemberID { get; set; }

    public string Title { get; set; }

    public string Surname { get; set; }

    public string Forename { get; set; }

    public string MiddleName { get; set; }
}

Data Entity

using System;
using System.Collections.Generic;
using System.Linq;    

namespace App.DAL.Entities
{
[Table("Member")]
public class MemberEntity    
{
    [Key]
    public int MemberID { get; set; }

    public string Title { get; set; }

    public string Surname { get; set; }

    public string Forename { get; set; }

    public string MiddleName { get; set; }

  }

}

Membership Context

 using App.DAL.Entities;

 public class MembershipContext :BaseContext<MembershipContext>
{
    public DbSet<MemberEntity> Member { get; set; }
}

WCF Data Contract

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Runtime.Serialization;

using App.Core.CoreInterfaces;

namespace App.Services.Contracts 
{
[DataContract]
public class MemberData : IIdentifiableEntity
{
    [DataMember]
    public int MemberID { get; set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public string Surname { get; set; }

    [DataMember]
    public string Forename { get; set; }

    [DataMember]
    public string MiddleName { get; set; }

    int IIdentifiableEntity.EntityId
    {
      get { return MemberID; }
      set { MemberID = value; }
    }
  }
}

generic repository

 public interface IGenericRepository<TEntity> where TEntity :class
{

    global::System.Linq.IQueryable<TEntity> GetAll();
    TEntity GetEntityByID(int id);
    void InsertEntity(TEntity obj);
    void UpdateEntity(TEntity obj);
    void DeleteEntity(int id);

}

Generic Repository Implementation

 public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    protected DbSet<TEntity> _DbSet;
    private readonly DbContext _dbContext;

    public GenericRepository()
    { }

    public GenericRepository(DbContext dbContext)
    {
        this._dbContext = dbContext;
        _DbSet = _dbContext.Set<TEntity>();
    }

    public IQueryable<TEntity> GetAll()
    {
        return _DbSet;
    }
   //...rest of code
 }

Member Repository

using App.Repository;
using App.DAL.Entities;

namespace App.Repository
{
public class Member_Repository: GenericRepository<MemberEntity>
{
    public Member_Repository() { }

    public Member_Repository(DbContext dbContext)
        :base(dbContext)
    { }
  }
}

Unit of work

using App.Repository;
using App.DAL.DatabaseContext;
using App.DAL.Entities;    

namespace App.Repository.UnitOfWork
{
 public class MembershipManagement_UOF:IDisposable
 {        
    protected Member_Repository _Member_Repository;  

   public Member_Repository Member_Repository
    {
        get
        {
            if (this._Member_Repository == null)
            {
                this._Member_Repository = new Member_Repository(_MembershipContext);
            }

            return _Member_Repository;
        }
    }    
  }

Now my issue is when I run code from business project, it should only talk to repository and use only Business entity for Member but it asking me to add reference from DAL in business project

here is code where I get Error

 using App.Repository.UnitOfWork;
 using App.Core.Entities;     

 public IEnumerable<Member> GetAllMember()
    {
        using (var _uof = new MembershipManagement_UOF())
        {
            var entities = _uof.Member_Repository.GetAll();

            // return entities.ToList();

            return null;
        }
    }

error

Severity    Code    Description Project File    Line    Suppression State
 Error  CS0012  The type 'Member' is defined in an assembly that is not referenced. You must add a reference to assembly 'App.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.  App.CoreServices    C:\My Work\Credit Union  Application\CreditSolutionApp\App.CoreServices\CoreServices\MembershipCore\MembershipCore.cs   23  Active

enter image description here

1
Where is MemberEntity defined?Maarten
sorry my fault I change data entities in DAL with MemberEntity to differentiate from business entitiesToxic
I have added using in code above aswelToxic
Youy _uof.Member_Repository.GetAll method returns MemberEntitys, which is defined in the DAL. Is there a conversion from MemberEntity (DAL) to Member (BAL) ?Maarten
no I don't have yet that conversion and I am not sure how to go about thatToxic

1 Answers

1
votes

You are now exposing methods/properties in the BAL classes which are using types from the DAL. Therefor, to use these BAL classes you need to know about the DAL. To solve this, you need to convert the DAL objects into BAL objects before returning them from the BAL.

The better solution is to let the BAL not know about the DAL objects either. The DAL should returns objects that the BAL can handle, and also can return to the caller. Any conversion from DAL types to BAL types is a concern of the DAL, not the BAL.