Adding System.Web reference to Business Logic Layer in n-layer Architecture

2k views Asked by At

I'm using TableProfileProvider to use ASP.NET profile system in an n-layer architecture.
The UI layer is a web application so I have to expose the profilecommon class to be able to use profiles.
Here's a simplified schema of my architecture:
UI: ASP.NET Web Application.
BusinessEntities: Pure POCO Classes. Persistence Igronace.
BLL: Business logic layer.
DAL: Data Access Layer.

The Profilecommon definition is:

 public class ProfileCommon : ProfileBase
 {
    public virtual ProfileCommon GetProfile(string username)
    {
        return (ProfileCommon)ProfileBase.Create(username);
    }

    public virtual string FirstName
    {
        get
        {
            return (string)base.GetPropertyValue("FirstName");
        }
        set
        {
            base.SetPropertyValue("FirstName", value);
        }
    }
 }  

In a simple design architecture where everything is defined in the web application project, I'd access the profilecommon as follows:
ProfileCommon strongleyTypedProfile = (ProfileCommon)this.Context.Profile;

I'd like to be able to access the Profile Common from my Business Logic Layer, So I moved the ProfileCommon definition to my BusinessEntities Library (Had to add reference to System.Web assembly in BusinessEntities library) and defined the new ProfileBLL Class:

public class ProfileInfo
{
    public ProfileInfo(ProfileCommon profile)
    {
        this.Profile = profile;
    }

    public ProfileCommon Profile { get; set; }

    public string GetFullName()
    {
        return this.Profile.FirstName + " " + this.Profile.LastName;
    }
}  

Now I can access profile common from UI like this:

var profileInfo = new BLL.ProfileInfo((ProfileCommon)this.Context.Profile);
txtFullName.text = profileInfo.GetFullName();

Now, is referencing System.Web in Business Layer/BusinessEntities Library violates the n-layer architecture disciplines? If so, What would you suggest in order to achieve this?

2

There are 2 answers

1
Pauli Østerø On BEST ANSWER

You can break the dependency on ProfileBase by implementing a interface instead. Lets say

public interface IProfile
{
    string FirstName { get; set; }
    string LastName { get; set; }

    IProfile GetProfile(string username);
}

public class ProfileCommon : ProfileBase, IProfile
 {
    public virtual IProfile GetProfile(string username)
    {
        return (ProfileCommon)ProfileBase.Create(username);
    }

    public virtual string FirstName
    {
        get
        {
            return (string)base.GetPropertyValue("FirstName");
        }
        set
        {
            base.SetPropertyValue("FirstName", value);
        }
    }
 }

public class ProfileInfo
{
    public ProfileInfo(IProfile profile)
    {
        this.Profile = profile;
    }

    public IProfile Profile { get; set; }

    public string GetFullName()
    {
        return this.Profile.FirstName + " " + this.Profile.LastName;
    }
} 

Now you don't have any dependency on System.Web.dll in your Business Logic but still have the freedom to implement the IProfile interface in your webapplication using the ProfileBase

0
John Saunders On

You should not be accessing System.Web from the business layer. That ties you to working with a web application. What if you wanted to reuse the business layer in a different kind of application?

You should ask yourself what you're trying to accomplish by this. Then, abstract that requirement into something generic reasonable for the business layer to access. This assumes that the business layer should know about users at all.