Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

N-Tier Architecture - Structure with multiple projects in VB.NET

I would like some advice on the best approach to use in the following situation...

I will have a Windows Application and a Web Application (presentation layers), these will both access a common business layer. The business layer will look at a configuration file to find the name of the dll (data layer) which it will create a reference to at runtime (is this the best approach?).

The reason for creating the reference at runtime to the data access layer is because the application will interface with a different 3rd party accounting system depending on what the client is using. So I would have a separate data access layer to support each accounting system. These could be separate setup projects, each client would use one or the other, they wouldn't need to switch between the two.

Projects:

MyCompany.Common.dll - Contains interfaces, all other projects have a reference to this one.
MyCompany.Windows.dll - Windows Forms Project, references MyCompany.Business.dll
MyCompany.Web.dll - Website project, references MyCompany.Business.dll
MyCompany.Busniess.dll - Business Layer, references MyCompany.Data.* (at runtime)
MyCompany.Data.AccountingSys1.dll - Data layer for accounting system 1 MyCompany.Data.AccountingSys2.dll - Data layer for accounting system 2

The project MyCompany.Common.dll would contain all the interfaces, each other project would have a reference to this one.

Public Interface ICompany
    ReadOnly Property Id() as Integer
    Property Name() as String
    Sub Save()
End Interface

Public Interface ICompanyFactory
    Function CreateCompany() as ICompany
End Interface

The project MyCompany.Data.AccountingSys1.dll and MyCompany.Data.AccountingSys2.dll would contain the classes like the following:

Public Class Company
    Implements ICompany

    Protected _id As Integer
    Protected _name As String

    Public ReadOnly Property Id As Integer Implements MyCompany.Common.ICompany.Id
        Get
            Return _id
        End Get
    End Property

    Public Property Name As String Implements MyCompany.Common.ICompany.Name
        Get
            Return _name
        End Get
        Set(ByVal value as String)
            _name = value
        End Set
    End Property

    Public Sub Save() Implements MyCompany.Common.ICompany.Save
        Throw New NotImplementedException()
    End Sub

End Class

Public Class CompanyFactory
    Implements ICompanyFactory

    Public Function CreateCompany() As ICompany Implements MyCompany.Common.ICompanyFactory.CreateCompany
        Return New Company()
    End Function

End Class

The project MyCompany.Business.dll would provide the business rules and retrieve data form the data layer:

Public Class Companies

    Public Shared Function CreateCompany() As ICompany
        Dim factory as New MyCompany.Data.CompanyFactory
        Return factory.CreateCompany()
    End Function    

End Class

Any opinions/suggestions would be greatly appreciated.

like image 964
Craig F Avatar asked Mar 17 '10 22:03

Craig F


People also ask

What is n-tier architecture of project?

An N-tier architecture divides an application into logical layers and physical tiers. Layers are a way to separate responsibilities and manage dependencies. Each layer has a specific responsibility. A higher layer can use services in a lower layer, but not the other way around.

What is n-tier architecture with example?

And there are n-tier architecture models that have more than three tiers. Examples are applications that have these tiers: Services – such as print, directory, or database services. Business domain – the tier that would host Java, DCOM, CORBA, and other application server object.

How many tiers are there in an n-tier application design?

N-tier architecture usually divides an application into three tiers: the presentation tier, logic tier and data tier. It is the physical separation of the different parts of the application as opposed to the usually conceptual or logical separation of the elements in the model-view-controller (MVC) framework.

What is difference between n-tier and 3 tier architecture?

They are the same basic architectural pattern, but 3-tier always has 3 tiers, while n-tier has a variable number of tiers.


1 Answers

A few comments.

I would avoid having a MyCompany.Common.dll assembly. These typically end up getting filled with all sorts of unrelated things which then get changed often requiring a rebuild of all of your assemblies.

I would name your assemblies with the application name as well as the company name. MyCompany.MyApplication.Business.dll is preferable to MyCompany.Business.dll. It is then easier to split applications into sub parts and to reuse code from multiple applications.

It's best to have separate contract assemblies for each type of implementation assembly you're going to have. In your case I would suggest the following:

MyCompany.MyApplication.Windows-Contract.dll
MyCompany.MyApplication.Windows.dll

MyCompany.MyApplication.Web-Contract.dll
MyCompany.MyApplication.Web.dll

MyCompany.MyApplication.Business-Contract.dll
MyCompany.MyApplication.Business.dll

MyCompany.MyApplication.Data-Contract.dll
MyCompany.MyApplication.Data.AccountingSys1.dll
MyCompany.MyApplication.Data.AccountingSys2.dll

From your description it appears that the AccountingSys1 and AccountingSys2 assemblies share a common contract hence only one contract assembly for the two implementation assemblies.

Contract assemblies should represent your design, not your implementation, and only change because of design changes. You should avoid having any "significant" code (to avoid bugs) and you should constrain the code to interfaces, enums, exceptions, attributes, event args, and structs - all with no "significant" code.

When setting up assembly references you should ensure that assemblies only ever reference contract assemblies, like so:

Data.AccountingSys1
    Data-Contract

Data.AccountingSys2
    Data-Contract

Business
    Business-Contract
    Data-Contract

Windows
    Windows-Contract
    Business-Contract
    Data-Contract (maybe)

Web
    Web-Contract
    Business-Contract
    Data-Contract (maybe)

As a result implementation assemblies never have a dependency on other implementation assemblies. When an implementation changes you only have one assembly to rebuild.

The exception to this rule is when creating inheritance hierarchies. For example, you may create a *.Data.AccountingSys.dll to define base classes for the two specific accounting system assemblies.

If you can follow all of the above then you will need to implement some sort of dependency injection approach to be able to create instances of objects from the interfaces in the contract assemblies. You could use an existing DI framework or create a third set of *-Factory.dll assemblies that contain your factory methods.

A further benefit of this kind of structure is that unit testing is much simpler and can be based on the contracts rather than the implementation, helping you to write clean, testable code.

This may seem like a lot of assemblies, but the benefits you get from keeping your code from creating nasty dependencies will significantly reduce the chance that your project will become too complex and will help drive good quality as you go. A little pain now will eliminate so much pain later.

like image 56
Enigmativity Avatar answered Nov 17 '22 03:11

Enigmativity