2

I have 3 layers in my solution:

  • DAL (which is accessing my DB with LINQ)
  • Business layer
  • Winform

In my DAL, I am returning a List with a specific type from my DB and I'm doing the same in my BLL.

When I want to use my function in my UI I get the error:

The type 'Reservation' is defined in an assembly that is not referenced...

Now I want to avoid having to reference my DAL in my UI.

As I'm new to this and couldn't find a clear answer on the web, could anyone help me out please?

My DAL function

public static List<Reservation> SelectListReservation()
{
    try
    {
        List<Reservation> lstReservation = new List<Reservation>();
        lstReservation = oExamenSgbdEntities.Reservations.ToList();
        return lstReservation;
    }
    catch (Exception e)
    {
        throw e;
    }
}

My BLL function

public static List<DataAccess.Reservation> GetListReservation()
{
    try
    {
        List<DataAccess.Reservation> lstToReturn = new List<Reservation>();
        lstToReturn = GetListReservation();
        return lstToReturn;
    }
    catch (Exception e)
    {
        throw e;
    }
}

How I call my BL function in my UI:

var lstRes = Manage.GetListReservation();
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Jeremy
  • 167
  • 11

3 Answers3

1

From the details in your question, it looks like you are using a Traditional N-Layer Architecture. In this architecture, the UI layer depends on the BLL, and the BLL depends on the DAL. That should be your reference structure: the UI project references the BLL project and the BLL project reference the DAL project.

What that means to you, is that you cannot use classes from the DAL in your UI; the UI shouldn't know the implementation of the DAL, because the DAL could change (like moving from a SQL Server database to an Oracle database). So in order to get data from the DAL to the BLL, you need to create a model class in your BLL and map all the data from the DAL class to it.

For example, in your BLL, you need to add a ReservationModel class that will map to the Reservation class in your DAL:

public class ReservationModel
{
    // Add the same properties that are in the Reservation class in 
    // the DAL to this class. The properties below are just for example
    public int ReservationId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public int CustomerId { get; set; }
}

Then in the BLL, change GetListReservation() method to return a ReservationModel with all the data mapped from the Reservation class in the DAL:

public static List<ReservationModel> GetListReservation()
{
    var reservationModels = new List<ReservationModel>();

    foreach (var reservation in SelectListReservation())
    {
        reservationModels.Add(new ReservationModel
        {
            // Again, these are made-up properties for illustration purposes
            ReservationId = reservation.ReservationId,
            StartDate = reservation.StartDate,
            EndDate = reservation.EndDate,
            CustomerId = reservation.CustomerId
        });
    }

    return reservationModels;
}
Lews Therin
  • 3,707
  • 2
  • 27
  • 53
  • I like this answer. However, I believe DAL classes **can** be used by the UI without explicitly referencing the DAL if hidden behind an interface. – JuanR Dec 14 '18 at 17:23
  • @JuanR I might be missing something but I don't think that's possible simply because where would the interface be? If it's in the DAL, the UI can't see it; if it's in the BLL, the DAL can't see it; if it's in the UI, the DAL and BLL can't see it. The BLL has to be the intermediary between the UI and the DAL (which is good because you can swap out the DAL or the UI and still use the core business logic). – Lews Therin Dec 14 '18 at 18:23
  • 1
    What I have done in the past is have a separate assembly for the interfaces. This assembly can then be referenced by all others (e.g. `SomeProject.Core`). – JuanR Dec 14 '18 at 19:48
  • Glad I could help. – Lews Therin Dec 14 '18 at 20:00
0

If you are cutting in, DAL, BL and P, your BL method can't return the same type that your DAL.

P uses BL and BL uses DAL

Therefore P is abstracted from DAL

Reservation needs to be used just by BL if its contained in DAL

Decouple your DAL type and your BL type or chose a different architecture.

MrVoid
  • 709
  • 5
  • 19
0

One solution is to create a library of data transfer objects (DTOs) that wrap the objects from the data layer, since they are defined in a separate assembly. The business layer can then make calls to the database and convert the results into these new classes.

This breaks the dependency between the Presentation layer and the Data layer, and also allows you to customize what you expose from Data -> Business and/or Business -> Presentation (you can aggregate several objects from the database into a single one, and you can expose much smaller objects where possible).

You can read more about it here: Create Data Transfer Objects (DTOs)

Rufus L
  • 36,127
  • 5
  • 30
  • 43