0

I'm trying to implement the Repository Pattern with UoW for our small Application. As far as i read the main Idea of the UoW is to expose the Repositories via one Context and to Save all Stuff in one step, f.e. with Transaction, to make sure the Operations are atomic.

Everything fine so far and I checked the examples like http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

The problem: We have a logical BusinessModel, which gets Data from the TFS API and a SQL-Database using Entitiy Framework. So we have seperate Systems and no Contexts. UoW still seems a good Idea to implement (Rollback, if one System could not save properly etc.), but does it need Repository as well? If I create a Repository, which hold just a List of the logical BusinessModel and gets the Data from EF/TFS API, I could do everything I'd like to in it.

Did I understand these two Concepts wrong? Or is just our environment not workingfor this Patterns?

Thanks in advance

Matthias

Edit: To show what I mean: We have a DataLayer.TFS Project, which we can query TFS-relevant data like this:

IEnumerable<WorkItem> tfsItems = TFS.QueryByParameter(criterias);

And we have a DataLayer.SQL Project, where we have the EF and query data like this:

        using (var context = new SimpleContextContainer())
        {
            //Some Tables to List  etc.
        }

Then we have a ugly procedure called Concat, which merges the two Lists:

    private static List<NewItem> Concat(IEnumerable<WorkItem> tfsItems, IEnumerable<OldDBItem> dbItems)
    {
        List<NewItem> result = new List<NewItem>();
        foreach(var tfsItem in tfsItems)
        {
            var tmpItem = new NewItem();
            tmpItem.PbiId = tfsItem.Id;
            //Do this for all properties

            result.Add(tmpItem);
        }
        return result;
    }

And we have an opposite Prodecure for splitting the Data.

Matthias Müller
  • 3,336
  • 3
  • 33
  • 65
  • Can you elaborate why you do not get a Context for free from EF in your logical business model? – Mare Infinitus May 27 '14 at 06:44
  • I do, but I want to synchronize the Saving of the TFS and EF + I dont want to have to merge two Objects in one Logical Unit in the BusinessFacade. – Matthias Müller May 27 '14 at 06:50
  • EF already implements repository and unit of work; why create another one on top of that? – L-Four May 27 '14 at 06:59
  • @MatthiasMüller Okay then, what is the reason why you do not get a Context from EF? This Context can be considered a unit-of-work. I do not see where EF generates a repository as L-Three said though. – Mare Infinitus May 27 '14 at 07:12
  • DbContext is your UoW (Unit of Work) and each DbSet is the repository. It is explained here (second answer): http://programmers.stackexchange.com/questions/180851/why-shouldnt-i-use-the-repository-pattern-with-entity-framework – L-Four May 27 '14 at 07:17
  • I have done a repository using the DbSets through a DbContext. It is easy to maintain and abstracts the whole persistance layer. I do not see why this should be redundant. In fact, I see more of a problem if you have DbSets spread around your domain code. I follow the aspects in this post: http://stackoverflow.com/questions/13180501/what-specific-issue-does-the-repository-pattern-solve/13189143#13189143 which states that EF is not a repository. – Mare Infinitus May 27 '14 at 07:43
  • Yes, there are different opinions about whether it has added value or not. – L-Four May 27 '14 at 07:58
  • So the Concating of the two objects (TFS Workitem and our DB-Workitem) would be done by the Repository? As said, we DONT just have Tables, we have a DataLayer per TFS API AND one per EF. – Matthias Müller May 27 '14 at 07:58
  • Can you give more information on what you mean with "concating"? It reads like you are aggregating some information. Perhaps you have a small example on that. – Mare Infinitus May 27 '14 at 08:19
  • I edited the main Post to show a bit Code. – Matthias Müller May 27 '14 at 08:36
  • And the result of your Concat is your domain model? – Mare Infinitus May 27 '14 at 09:23
  • I'm not sure what you mean with Domain Model. It is the Model, which gets returned by the Facade and which the Client is working with. We call it BusinessModel. – Matthias Müller May 27 '14 at 10:17
  • So it's not only data, but also behavior? In other words, is it a business/domain model or anemic? – L-Four May 27 '14 at 10:19
  • They're just DTOs, so a List of Properties. But the Properties contain Data from the Database and the TFS. – Matthias Müller May 27 '14 at 10:29
  • So they are DTO's, and not your domain. So it's all about mapping data. Maybe AutoMapper can help you here. – L-Four May 27 '14 at 10:31
  • Yeah, but where should this Mapping happen? In the Repository? In the Unit of Work? In my opinion, it should not happen in the BusinessFacade, because it is not Business Logic. Or am I wrong? – Matthias Müller May 27 '14 at 10:43
  • Mapping between data entities and business entities happens in data layer (repositories). But y our entities are DTO's, so I'm not sure what you mean with business facade, because you don't have business entities. Unit of work is normally in your application layer, not in repositories. – L-Four May 27 '14 at 10:52

1 Answers1

1

It is not easy to tell what your architecture is here. But I think you can go with something like this:

Business-Layer: Work with your domain objects, your "business".

Domain-Layer: Your domain objects, accessing data from repositories to build them, merge them, provide constraints, etc

Data-Access-Layer: Repositories, one for each source

Persistence-Layer: Unit of Work

Data-Layer: SQL Database, TFS

Data-Access-Layer and persistence layer can be merged in case of TFS. For the SQL Database you get a context from EF, which should be used in that case in the data access layer. So you have methods like AddEntities or DeleteEntities there.

You can have constraints on the different layers of course.

The repository usually gives back full functional domain objects. So if you achieve that, you are on the right way I think. The domain-layer that I wrote above is now in place as far as I understood your comments. Perhaps you can and should get rid of that, replaced by a single assembly that defines your business objects that is used by the Repository and your business layer.

Mare Infinitus
  • 8,024
  • 8
  • 64
  • 113
  • Thank you, like this seems like the way to go. Sadly it's not that easy to bring TFS and EF together with LINQ etc. But at least I see now how it SHOULD be – Matthias Müller May 27 '14 at 12:46