Currently I'm using DI and service locator pattern to get the instance of Service. (Note that Service just generic term im using, and is nothing but the C# class which calls EF repository and perform data operations. Its NOT WCF service)
Is it okay to have Service instance in ViewModel? If yes, the what's the proper way to pass Service instance?
1>Should the controller pass the service instance to ViewModel. In this case Service properly get disposed when controller get disposed
2>or should the ViewModel get service instance using DI & Service Locator. In this case how service will get disposed?
BaseController
public class BaseController:Controller
{
private MyDomainService _myDomainServiceInstance = null;
protected MyDomainService MyDomainServiceInstance
{
get
{
if (_myDomainServiceInstance == null)
{
_myDomainServiceInstance = DefaultServiceLocator.Instance.GetInstance<MyDomainService>();
}
return _myDomainServiceInstance;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (_myDomainServiceInstance != null)
{
_myDomainServiceInstance.Dispose();
}
}
}
Controller
public class MyController:BaseController
{
public ActionResult DoSomething()
{
var model = new SummaryVM(MyDomainServiceInstance);
}
}
ViewModel
public class SummaryVM
{
MyDomainService _myDomainService = null;
public SummaryVM(MyDomainService myDomainService)
{
//Approache 1: Controller is passing the service instance
_myDomainService = myDomainService;
}
public SummaryVM()
{
//Aprooche 2: Use DI & Service locator pattern to get the instance
_myDomainService = DefaultServiceLocator.Instance.GetInstance<MyDomainService>();
}
public int[] SelectedClients { get; set; }
public string[] SelectedStates { get; set; }
public IEnumerable<Clients> PreSelectedClients
{
get
{
if (SelectedClients == null || !SelectedClients.Any())
{
return new List<AutoCompletePreSelectedVM>();
}
return _myDomainService.GetClients(SelectedClients);
}
}
}
I had passed through similar situation. I think it is okay having the domain service get instantiated inside view model. The domain service can implement IDisposable, so I would instantiate it inside the get method instead of create the service as an attribute.