Question

I am trying to design an application in 3 layers :

1) Data access layer
2) business layer
3) UI

I try to keep classes decoupled so on the business layer I have created interfaces for the Data access classes like this :

public interface ICountryRepository:IRepository 
{
    Country  GetCountry(int ID);

    int CreateCountry(Country obj);
    Boolean UpdateCountry(Country obj);
    Boolean DeleteCountry(Country obj);
    ...
    ...
 }

and i pass the interface as param to the service constructor :

   public CountryService(ICountryRepository repository,ILanguageRepository lang_repository)
   {       
    ....
   }

But on the CountryService for example I need to load the current user and his permissions so I can check if the operation can be applied :

    public Country GetCountry(int ID)
    {

        if securityService.UserHasPermission(currentUser, GetPermission("CanGetCountry"))
        {
           return repository.GetCountry(ID);
        }
        else
        { 
           Throw(New SecurityException("No permissions for that operation ...."))
        }

    }

That means I have to instantiate the SecurityDataAccess object and pass it to the constructor of the SecurityService on my business layer assembly which I try to avoid for keeping objects decoupled. Right now I even don't have a reference to any DataAccess assembly on my business assembly.

I am thinking of using an IoC container here. Using external configuration I could get the right class/assembly from a config file. But I am not sure that is the right solution because it is said that IoC containers should be used in one place to keep things simple and it should be the top level assembly (the UI assembly) most of the time.

Anybody has a suggestion for solving this problem ?

Was it helpful?

Solution

Why not add the security service into the constructor of the Country service? That way the IOC Container could resolve the dependency and inject the security if it is needed. That mean the IOC Container would take care of constructing your CountryService object. And you would use the container to get all Services.

Another option could be to "normalize" your repository a bit...

Trim it down to it only has 4-5 basic functions that are identical for all repositories, then use generics to make them all look alike, so no

UpdateCountry(...) but Update(T object)

Something like this: http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx

Then you can use a Chain of reponsibilty pattern to place your security code before the DB Code ( http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern )

So you could have a SecurityChecker that validates access, throws an exception if invalid, or passes down the request in the next link in the chain (You can also add a logging dynamically that way, or timing or whatever)

OTHER TIPS

Do you need to implement security in the Data Access layer? If you move your security service to the business layer as Heiko suggests. In other words, perform security in the business layer and you avoid the IoC issue altogether.

This may be off-beam, apologies if it is, I'm a lurking Java EE programmer. It seems to me that authorisation is of methods is better addressed in the infrastructure, declaratively.

This article appears to suggest that .Net, like Java EE offers a facility to control access declaratively. Does this approach work for you?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top