The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Unit of Work

Hello
I'm trying to implement the Unit of Work pattern as desribed in the P of EAA book. So I have two projects DomainModel and DataAccess. In the Domain model project I have defined my domain objects and in the data access project the the data mappers. Now in the domain model project i have defined the IUnitOfWork interface as below:

    public interface IUnitOfWork
    {
        void RegiserNew(DomainEntity entity);
        void RegisterDeleted(DomainEntity entity);
        void Load(DomainEntity entity);
        void Commit();
    }

and I have implemented this interface in the data access project in a UnitOfWork class. I have included the RegisterNew() and RegisterDeleted() methods in th interface because I wannt to register automatically the new objects in their constructor and I want to register them deleted when the Delete() method is called in domain entities.
The problem I have is that since these methods are public they can be called directly from UI layer which I do not want to. I want the UI layer to only call Load() and Commit() methods.
Is there any solution or am I implementing the pattern in the wrong way?

Any help is appreciated!
Thanx
Albert
Albert Tollkuçi Send private email
Thursday, October 26, 2006
 
 
On a per method basis, indicate whether those methods are private, shared or public. In other words...

  public void Load( DomainEntity entity )
  private void RegisterNew( DomainEntity entity )
TheDavid
Thursday, October 26, 2006
 
 
Since they are part of the interface they are always public...
Albert Tollkuçi Send private email
Thursday, October 26, 2006
 
 
If he's using .NET (looks like it), they are all public instance members.  Well, he can "fake" private by implementing the interface explicitly, but anybody can cast an object to an interface and call the methods, so they're still more or less public.
Charlie Williams Send private email
Thursday, October 26, 2006
 
 
That's weird. I thought he was just using standard C++, or intended to "convert" the psuedocode into Java.

C++.NET requires all methods to be public? Or are you thinking of C#.NET?

(I don't use .NET at all and that would be a major gotcha I'd want to watch out for.)
TheDavid
Thursday, October 26, 2006
 
 
These methods are not members of a class, but an interface, and interface members are public by definition in C#.

A possible solution might be splitting the interface into two, and put the last two methods in the second interface intended for the UI layer. (Not knowing too much about the structure, this is of course mostly guesswork.)
Arpad Miklos Send private email
Friday, October 27, 2006
 
 
(As for the implementing class, Charlie Williams' reply applies. Marking actual interface method implementations as private does not really help.)
Arpad Miklos Send private email
Friday, October 27, 2006
 
 
Sorry for not making it clear....I'm using C#. The structure of the application is something like this:
              UI
          --      --
      --            --
      |              |
  DataAcccess -->  DomainModel

so UI references DataAccess and DomainModel and DataAccess references DomainModel. The IUnitOfWork is defined in the DomainModel and the implementation in DataAccess.
So far the best option seems to split the interface...but I'm still not very happy with that...
Albert Tollkuci Send private email
Friday, October 27, 2006
 
 
Could you get around the problem by creating two interfaces:

  public interface IUnitOfWorkNotForUI
    {
        void RegiserNew(DomainEntity entity);
        void RegisterDeleted(DomainEntity entity);
    }

  public interface IUnitOfWorkForUI
    {
        void Load(DomainEntity entity);
        void Commit();
    }

Then have your class implement both of the interfaces?
devuser Send private email
Friday, October 27, 2006
 
 
With two interfaces still the IUnitOfWorkNotForUI interface should be in the domain model since it will be used by the domain objects so it will be accessible from the UI...I need a way for this interface to be accessible only from the domain model and the data access but not from the UI...
Maybe I need another project...
Albert Tollkuci Send private email
Friday, October 27, 2006
 
 
Make the "non-public" interface internal to the project your domain model lives in and always implement it explicitly.  Your UI layer won't be able to call its members since they can't cast to (or even see) the interface.
Charlie Williams Send private email
Friday, October 27, 2006
 
 
If it's internal then I cannot implement it in the DataAccess layer...
Albert Tollkuçi Send private email
Friday, October 27, 2006
 
 
You could create IUnitOfWorkNotForUI as internal and then set the data layer to be a friend assembly and allow it to see the internal.

http://msdn2.microsoft.com/en-us/library/0tke9fxk.aspx
Graeme Bradbury
Wednesday, November 01, 2006
 
 
Seems to me like you've got the wrong design alltogether.

Your UI should not talk to the data access, to me that's "arse about face".

Your Data access layer should be a low level layer, perhaps the lowest level. It should interact with your DB directly.

Above this you have your domain model. Your domain objects have static methods like Retrieve, Update, Insert etc which use your DataAccess layer to perform these operations against the persistant store.

Next you have a facade layer. This will provide service level functionality to the clients, and should talk directly to the domain layer. This might be overkill, depending on the size of your project. The facade provides a logical grouping of different areas of functionality.

Above the facade layer you might even have a transport layer which exposes facade methods as web services or Remoting services.

Your UI talks directly to your facade (or transport if you have that layer. It should never talk to your data access layer. Data access should be transparent above the domain layer.

Also, your UnitOfWork interface should not be in your domain model (wtf?). You might want to create a Framework project and stick it in there. Then utilise it within your DAL. The domain layer is really only your business objects plus the static CRUD methods which use your DAL. You'll also have some private stuff such as MarkClean and RegisterDirty etc.

UserIInterface
  |
  |
(Transport)
  |
  |
Facade
  |
  |
Domain
  |
  |
Data Access ( Mappers )
  |
  |
[Database]
redeye Send private email
Thursday, November 02, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz