Question

I want to know if I am on the right track of thought here, I am programming mainly to interfaces so I want to know if the classes below should be injected via DI or should I instantiate a class myself...

Note: these services are held in my core libaray not my web app (asp.net mvc)

//IUserSession is never known, this depends on client app, this is never known so I must inject at all times

//IWorkflowService I need to inject as client app have a few different services/ packages, depending on that the business rules could vary

//IReadonlySession is only ever 1 in my app so I never need to inject? could be different in other client calls but unlikely

//INotificationService will always be whatever I say it is, it is always ever going to be one thing, so I should program against an interface and not inject?

private readonly IUserSession _userSession;
private readonly IReadOnlySession _readonlySession;
private readonly INotificationService _notificationService;

public Processor(IUserSession userSession, IWorkflowService workflowService)
        : base(workflowService)
    {
        _userSession = userSession;
        _readonlySession = new ReadonlySession();
        _notificationService = new NotificationService();
    }

//IReadonlySession is injected, as this could change depending on if I am running tests, I may use a different database, or I may call my code from a different client app (unlikely but possible)

public Processor(IUserSession userSession, IWorkflowService workflowService,   IReadonlySession readonlySession)
        : base(workflowService)
    {
        _userSession = userSession;
        _readonlySession = readonlySession;
        _notificationService = new NotificationService();
    }

Question:

Is my instantiation of objects correct? Is the way I have implemented it correct?

Was it helpful?

Solution

There's little gained from programming against an interface if you still have a hard coupling to NotificationService, so I would say

  • either inject INotificationService
  • or program against the concrete class

As there seems to be some appropriate defaults, you should consider Constructor Chaining:

public Processor(IUserSession userSession, IWorkflowService workflowService)
    : this(userSession, workflowService, new ReadonlySession()) { }

public Processor(IUserSession userSession,
    IWorkflowService workflowService, IReadonlySession readonlySession)
    : base(workflowService)
{
    _userSession = userSession;
    _readonlySession = readonlySession;
    _notificationService = new NotificationService();
}

This will give the consumer of your library an easy way to get started without constraining advanced users.

You may also want to use the Facade solution outlined here: Dependency Inject (DI) "friendly" library

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