0

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'

Business Entity

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

namespace App.DAL.Entities
{
[Table("Member")]
public class Member
{
    [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; }

  }

}

WCF Data Contract

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);

}

Unit of work

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

 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
K.Z
  • 5,201
  • 25
  • 104
  • 240

1 Answers1

1

It's a bit difficult to tell from the original post, but I suspect that your concrete implementation of the IGenericRepository interface is referencing the Member class from the DAL rather than from the BLL (Business Logic Layer). The concrete repository needs to use the Member class from the BLL as its generic TEntity type. The methods of the concrete repository class need to load the data from the DB using the DAL Member class, and then map those DAL Member instances to BLL Member instances, and then return the BLL Member instances.

Renaming the DAL Member class to something like MemberDto might help avoid confusion here. So, you might end up with something like (where IGenericRepository<TEntity> is in your BLL and MyMemberRepo is in your DAL):

public class MyMemberRepo : IGenericRepository<Member>
{
    public IEnumerable<Member> GetAllMember()
    {
        // 1. Load the data from the data store into an IEnumerable<MemberDto>.
        // 2. Map the IEnumerable<MemberDto> to an IEnumerable<Member>, perhaps
        //   using something like the open source AutoMapper project.
        // 3. Return the IEnumerable<Member>.
    }
    // ... other interface implementations...
}
wablab
  • 1,703
  • 13
  • 15
  • if I use concrete implementation of the IGenericRepository interface is referencing from the BLL (Business Logic Layer) then how I will handle DbSet and because all they all referring to DAL entities where it define primary, foreign keys and table name – K.Z Jun 15 '16 at 13:40
  • The main app references the BLL, the BLL references the DAL, and the DAL uses ADO.NET or LINQ2SQL or Entity Framework or whatever you want to access the DB. Since the app is only referencing the BLL, it can only reference the `IGenericRepository` interface; it can't directly reference the concrete repository. Therefore, you'll need to use reflection or some form of inversion of control (IoC) in order to instantiate the concrete implementation of the `IGenericRepository` interface. IoC is beyond the scope of this question. – wablab Jun 15 '16 at 13:45
  • @toxic, sorry, I misspoke in my previous comment. The main app references the BLL, and the DAL references the BLL as well (since the BLL contains the `IGenericRepository` that the `MyMemberRepo` class would need to implement). The rest holds true. – wablab Jun 15 '16 at 13:53
  • Thats good I got roughly understanding of whats going on. I have another idea ... define entities in business layer and in data access layer use Fluent API on business entities in override method and use that only and delete the entities in data access layer that way I am not duplicating entities but same time I am use same entities... what your thoughts on that – K.Z Jun 15 '16 at 14:04
  • @toxic, this is where it comes down to a question of judgment that you'll need to make. A purist would say that you should keep your `MemberDto` classes in the DAL since they're adorned with `[Table]`, `[Key]`, etc. attributes, which are data-access specific. In many cases, this is sound advice since it strictly separates concerns between the layers, and it can make your application more flexible and maintainable in the long-term. However, that flexibility comes at the cost of "duplicate work" (i.e. the essentially duplicated entities and the mapping tasks). – wablab Jun 15 '16 at 14:17
  • @toxic, (continued) In other cases, the way you described is perfectly acceptable and quite appropriate. For example, if you know that your data will always be stored in a DB that your DAL supports (e.g. SQL Server), then you might be better off eliminating the DAL entities and letting the concerns "bleed" through between layers, since it will allow you to focus your time on more value-creating activities (i.e. the main business logic of your app). – wablab Jun 15 '16 at 14:17