EF code first with Repository and unit of work

339 Views Asked by At

I am implementing a solution using EF code first, with Repository pattern and unit of work to do a correct separation. I am driving crazy trying to find the correct approach.

So my solution looks like:

  1. DataAccess Project where I write my code first classes (Currenty I only have one: Posts.cs) and wrote my DBContext, y also added here other classes I needed for example for login and I marked them as [NotMapped](I know...it doesn't make sense)

  2. Repository: Where I implemented Repository Pattern and Unit of Work

  3. WCF service project: Here I access the unit of work like:

    var posts= unitOfWork.PostRepository.Get()
    

here it's all good, but I might need to do this:

unitOfWork.PostRepository.Insert(Post)    

and now all the purpose of decoupling dataAccess goes to shi** because I need to reference DataAccess project.

So, couple of questions:

  1. Which is the best approach, how can I have a model separated?
  2. I don't have a business layer, all logic like login to active directory, it's ok to put it in WCF project?

Please help!!!

1

There are 1 best solutions below

2
On

The problem you're describing here took me a real long to get my head around a few years ago. You're definitely on the right track wanting to separate data access and business logic, and the business logic should be in its own project, so what you need to do is create an abstraction in the form of an repository interface. Something like:

interface IPostRepository
{
    void Insert(Post post);
    void Update(Post post);
    void Delete(int postId);
    Post GetById(int postId);
}

This interface must be placed in the business logic project, since your business logic needs to be able to read and write data.

In your data access you layer you implement this interface, so you will need to have a reference from the data access layer to the business logic, but not the other way around.

And finally, somewhere you need to tie the interface and the implementation together, and that should be done in the WCF service project, which means that it has references to both the data layer and the business layer. With this setup, you can have a WCF service method that looks something like below.

void InsertPost(Post post)
{
    using (var db = new DbContext())
    {
        var postRepository = new PostRepository(db);
        var postService = new PostService(postRepository);

        postService.Insert(post);

        db.SaveChanges();
    }
}

Now this looks a bit strange since PostService seemingly has to know about PostRepository. But the constructor of PostService looks like this:

public PostService(IPostRepository postRepository)
{
    _postRepository = postRepository;
}

The manual construction of PostRepository and PostService in the example above is far from ideal. I would really recommend that you take a look at an Inversion of Control container that makes most of this decoupling and layering a breeze. There are several out there: Autofac, Unity, Ninject etc.