views:

119

answers:

6

Hi All,

This may not be at all possible but I thought I'd get your responses before we gave up the Idea.

We have 3 main projects all in one Solution: Interface, Logic, and Data Access. The Data Access Project contains all the Object Classes with their variables and methods. The Logic Project contains classes that hold logic methods and also 2 classes that deal with the saving and loading of objects from the Data Access Project. The Interface project is the User interface and any classes and methods that need to be in here / don't need to be in the logic layer.

We intended to keep a clear separation and keep a communication of Interface --> Logic --> Data Access and back the same way. This is all fine but unfortunately for the Interface to understand the Data Access Class Object being passed back through with its values we obviously need to add a reference to the Data Access Project in the Interface Project.

Hopefully I haven't lost anyone already?

Now obviously we are fine with allowing the Interface to read the values from the Data Access Project but we do not want the interface Project calling any methods as these are all handled through the Logic Layer in specific ways. I know this is only a design time problem but is there anyway that we can set the methods to not be callable from certain projects?We don't want to capture what project is calling the method at runtime as this is too late.

This may sound like an overkill question but since my colleague and I may not be the only developers working on this after it is released to the company we want any other developers to follow the strict guidelines and structure of the solution and projects. We could write it all down and try to make sure that they read it before working on the application but as we all know if you're urgently asked to work on something there is no guarantee that you'll have time to read another developers Technical specification about the application first.

If you need any more information to come up with any solutions please ask away.

Many Thanks all,

Louis Russell

A: 

You should checkout the Managed Extensibility Framework for dependency injection....

Goober
How does this prevent somebody from directly accessing DAL code from the presentation layer?
Pete OHanlon
A: 

I wouldn't normally recommend this, but you could always add a Debug time check that looked at the StackTrace to see what the parent level objects were. Basically, you'd walk up the trace until you encountered the level above (by checking the assembly of the relevant type) - if you didn't encounter it (i.e. you reach the top level assembly), then you'll throw an exception.

The reason for this being Debug only, is that you don't want to burden your release application with what is effectively redundant code.

Pete OHanlon
+1  A: 

You can use InternalVisibleTo attribute, and mark the methods for which you want to restrict access internal.

Note : In your case, I would not use this. I would prefer rethink the design. It seems a bit odd that your domain objects are located in a "data access project". Why don't you have a UI project, a Logic project, a Data access project and a Model project?

Romain Verdier
A: 

Perhaps it would be better to put these interfaces in the logic project? If you look at some schools of thought like Domain Driven Design, the interfaces to the data access (in DDD case repository interfaces) are actually part of the Domain's (aka logic) concern (rather than the Data layer) and so often end up in a different project.

UpTheCreek
+1  A: 

You could abstract the data storage classes (i.e. the classes you pass around) into a seperate project that is referenced by both the data access and interface projects. You could then remove the data access project reference from the interface project.

m_arnell
A: 

Your problem appears because you allow the top layer (User Interface) to reference types from the bottom layer (Data Access). Don't do this.

Instead, define some Abstractions (interfaces or base classes) that your User Interface should program against. You can put those Abstraction in the Logic layer or a new library.

Your Data Access library should then implement those Abstractions.

You can use Dependency Injection (DI) to inject the real Data Access library into the User Interface at run-time without actually having any hard reference between those two.

This can be done manually or by using a DI Container such as Castle Windsor to wire up the dependencies.

Mark Seemann