0

I'm somewhat new to the onion architecture. I created a service layer that calls repositories in the DAL by manually passing them into the constructor. But now looking at my method I'm using an object from the core domain and I'm wondering if I should have passed in an interface to access it as well? Should all objects be accessed via an interface being passed in via parameter, constructor, property, etc?? I know this would make it less coupled, but in terms of best practices where does this stand?

Here in my code I'm wondering if

DiaryEvent diaryEvent = new DiaryEvent();

should be used as an interface instead of a concrete object. P.S. DiaryEvent is coming from the layer (core) below.

public class DiaryEventService : IDiaryEventService
{
    private readonly IYogaSpaceEventRepository yogaSpaceEventRepository;

    public DiaryEventService() : this(new YogaSpaceEventRepository())
    {

    }

    public DiaryEventService(IYogaSpaceEventRepository yogaSpaceEventRepository)
    {
        this.yogaSpaceEventRepository = yogaSpaceEventRepository;
    }

    public  List<DiaryEvent> LoadAllAppointmentsInDateRange(double start, double end)
    {
        var fromDate = ConvertFromUnixTimestamp(start);
        var toDate = ConvertFromUnixTimestamp(end);

        var yogaSpaceEvents = yogaSpaceEventRepository.Find(fromDate, toDate);

        List<DiaryEvent> result = new List<DiaryEvent>();

        foreach (var item in yogaSpaceEvents)
        {
            DiaryEvent diaryEvent = new DiaryEvent();
            diaryEvent.ID = item.YogaSpaceEventId;
            //diaryEvent.SomeImportantKeyID = item.SomeImportantKey;
            diaryEvent.StartDateString = item.DateTimeScheduled.ToString("s");
            // "s" is a preset format that outputs as: "2009-02-27T12:12:22"
            diaryEvent.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("s");
            // field AppointmentLength is in minutes
            diaryEvent.Title = item.Title + " - " + item.AppointmentLength.ToString() + " mins";
            diaryEvent.StatusString = Enums.GetName<AppointmentStatus>((AppointmentStatus)item.StatusEnum);
            diaryEvent.StatusColor = Enums.GetEnumDescription<AppointmentStatus>(diaryEvent.StatusString);
            string ColorCode = diaryEvent.StatusColor.Substring(0, diaryEvent.StatusColor.IndexOf(":"));
            diaryEvent.ClassName = diaryEvent.StatusColor.Substring(diaryEvent.StatusColor.IndexOf(":") + 1,
                diaryEvent.StatusColor.Length - ColorCode.Length - 1);
            diaryEvent.StatusColor = ColorCode;
            result.Add(diaryEvent);
        }

        return result;
    }

    private static DateTime ConvertFromUnixTimestamp(double timestamp)
    {
        var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return origin.AddSeconds(timestamp);
    }
}
Jupaol
  • 21,107
  • 8
  • 68
  • 100
chuckd
  • 13,460
  • 29
  • 152
  • 331

1 Answers1

0

But now looking at my method I'm using an object from the core domain and I'm wondering if I should have passed in an interface to access it as well?

Looking at your code above, it looks like you are doing it right. DiaryEvent looks like a structure i.e. data object with no behaviour, so no need to replace it with interface. Interface out objects helps in injecting them at runtime and here since you are not invoking any behaviour i.e. method of DiaryEvent it is fine to instantiate them into the method directly.

Should all objects be accessed via an interface being passed in via parameter, constructor, property, etc??

Nah, not really. Think it this way, if you are invoking a method from within a class, the class becomes dependent on the behaviour of invoked method/class. To make it loosely coupled i.e. changing the behaviour at run time/mocking it, you will need to inject this dependency. For injecting a dependency from outside you need to interface out or abstract the dependency.

A good way to verify that your class is loosely coupled is to write a unit test case for its methods mocking dependencies.

SBirthare
  • 5,117
  • 4
  • 34
  • 59
  • just a quick question. I'm using onion architecture so I shouldn't have any methods inside my domain classes, right? All business logic is contained in a outer layer from the core? You suggested that I might have methods inside my classes. – chuckd Mar 24 '15 at 06:17
  • When you say domain classes, you mean entities i.e. DB table? If yes, then answer to your first question is YES, you should not have any methods inside you entity class. It just a data holder and represents a row of a DB table in DB. Business logic will be contained in a separate layer, fetching entities (sometime called model object) and applying business logic. Business or service layer often return the model object. At presentation layer you convert them into ViewModel object before handing over it to view. – SBirthare Mar 24 '15 at 06:26