I am trying to implement Unity as an IoC container in a learning project I am working on. I have a layered application, UI->Service->Logic->DataAccess.
It's an MVC Application on the UI side.
In my controller, I have a constructor:
public HomeController()
{
_container = new UnityContainer();
_container.RegisterType<IUserService, UserService>();
_container.RegisterType<IUserLogic, UserLogic>();
}
I then attempt to use the IService in one of my methods:
var service = _container.Resolve<IUserService>();
ReplyDto reply = service.Login(model.Email, model.Password);
But then get this error:
Resolution of the dependency failed, type = "Services.IUserService",
name = "(none)".
I'm not sure why it's saying this. Do I maybe have an issue with MVC and the constructor? Breakpoint on the Resolve line shows that the _container does have the interface I am trying to resolve.
My UserService class has this in the constructor:
private IUserLogic _userlogic;
public UserService(IUserLogic logic)
{
_userlogic = logic;
}
The Logic layer class is defined like this:
public class UserLogic : IUserLogic
{
public ILog _logger;
public IData _data;
public UserLogic(IData data, ILog logger)
{
_data = data;
_logger = logger;
}
I am still in the process of propagating the IoC patter down through all layers.
And finally, the data access layer is defined as:
public class Data :IData
{
Log _logger = new Log();
MyEntities entities;
public Data()
{
entities = new MyEntities();
var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
}
My _container has reference to the IUserLogic interfaces and which concrete class to use.
UserLogic(IData data, ILog logger) - neither IData nor ILog shown as registered in container - so if code is exactly like you have in the post it is the reason why IUserLogic can't be resolved when unity tries to pass argument to UserService(IUserLogic) constructor.
Fix: register all dependencies (recursively)
To achieve that consider:
make sure types with no dependencies has constructors without arguments
register instances instead of types - if that works for your system
make constructors depend on concrete types (as all concrete types by default registered with Unity) - not testable choice...
provide parameters for all non-interface/non class arguments like int/string (How resolve a dependency with unity passing arguments in the constructor?)
You should register container in the Global.asax.cs
public class Global : HttpApplication
{
private void Application_Start(object sender, EventArgs e)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IUserService, UserService>();
container.RegisterType<IUserLogic, UserLogic>();
UnityDependencyResolver dependencyResolver = new UnityDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
DependencyResolver.SetResolver(dependencyResolver);
}
}
Related
Here is my class where dependencies are resolved
namespace TestProj
{
public static class Bootstrapper
{
public static void Run()
{
SetAutofacWebAPI();
}
private static void SetAutofacWebAPI()
{
var builder = new ContainerBuilder();
builder.RegisterType<UserService>().As<IUserService>().InstancePerRequest();
builder.RegisterType<Encryption>().As<IEncryption>().InstancePerRequest();
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
}
}
}
In the Global.asax, I have this : Bootstrapper.Run();
Here is my UserService class:
public class UserService : IUserService
{
private readonly IEncryption _Encryption;
public UserService(Encryption Encryption)
{
_Encryption = Encryption;
}
//Rest of the service here
}
the Encryption class is a similar one.
And the controller is here :
public class UserController : Controller
{
private readonly IUserService _UserService;
public AccountController(UserService UserService)
{
_UserService = UserService;
}
public JsonResult GetLoginLogs(int Id)
{
var Logs = _UserService.GetLoginLogById(Id);
return Json(Logs, JsonRequestBehavior.AllowGet);
}
//The rest of the controller
}
here is the version info:
Autofac : 3.5.2
MVC : 4.0.40804.0
DOTNET : 4
And then, when try localhost:5000/Account/GetLoginLogs/1 this exception comes up:
No parameterless constructor defined for this object.
Someone please help. I am in seriously in trouble!
I think you are confusing how you registered the dependencies.
Update from comments by #Amy:
You also failed to register your MVC controllers
// You can register controllers all at once using assembly scanning...
builder.RegisterControllers(Assembly.GetExecutingAssembly());
Source: documentation
Also use the interfaces instead of the concrete classes when explicitly injecting into the dependent classes as that is what you registered with the container.
public class UserService : IUserService {
private readonly IEncryption _Encryption;
public UserService(IEncryption Encryption) {
_Encryption = Encryption;
}
//Rest of the service here
}
public class UserController : Controller {
private readonly IUserService _UserService;
public AccountController(IUserService UserService) {
_UserService = UserService;
}
public JsonResult GetLoginLogs(int Id) {
var Logs = _UserService.GetLoginLogById(Id);
return Json(Logs, JsonRequestBehavior.AllowGet);
}
//The rest of the controller
}
Actually, I believe the exception you get is not misleading if you get deeper into it and analyze the exception message and stack trace. You would find exactly which service could not be found and created by the container - in this case it would be UserService in AccountController (and later, Encryption in UserService as well). The exception with "no parameterless contructor found" simply says that in existing contructor with parameters there is one or more parameters which cannot be resolved by the container, and, because the parameterless constructor is missing, required type cannot be created.
It can also mean you forgot to register your controllers in the container, so the Autofac has no idea it should inject any dependecies into the controllers.
Going further - Autofac is very explicit with the registrations - you can only inject/resolve what you registered at the start up of the application.
If you simply use builder.RegisterType<UserService>() - without any As<> you can only inject UserService directly. But when you add .As<>: builder.RegisterType<UserService>().As<IUserService>(), you cannot inject UserService anymore, but IUserService. To keep the possibility to inject UserService you would have to use AsSelf(): builder.RegisterType<UserService>().As<IUserService>().AsSelf(). Then, you can inject both IUserService and UserService. Keep in mind Autofac registration API is fluent, you can amend as many As<> as you want.
In Dependecy Injection world we do not like tidly coupled components, so injecting concrete classes, instead of interfaces - like you did - is not recommended - you should use interfaces wherever it is possible. So your registrations are correct, but you should inject IUserService instead of UserService and IEncryption instead of Encryption in your components.
It would ease potential unit testing of these components, allowing you mocking up dependencies easily.
Also, you should register your controllers as well:
builder.RegisterControllers(Assembly.GetExecutingAssembly());
I'm very new to dependency injection and I've just set up Unity.Mvc5 and has some success with it. But now I face the problem of multiple contructors in my controller class. I already have constructors that handle my UserManager and following tutorials I understand I need another constructor to instantiate my interface. When I do this however, I get the following error:
The type OrganisationController has multiple constructors of length 1. Unable to disambiguate.
A snippet from my controller:
private IPush _pushMessage;
// Here is the problem!
public OrganisationController(IPush pushMessage)
{
_pushMessage = pushMessage;
}
public OrganisationController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public OrganisationController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
var provider = new DpapiDataProtectionProvider("MyApp");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("PasswordReset"));
}
public UserManager<ApplicationUser> UserManager { get; private set; }
And my UnityConfig.cs as follows:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IPush, PushMessage>();
container.RegisterType<IController, OrganisationController>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
I am not sure how to tell Unity that I have another constructor being used to implement an interface.
When using DI, constructors are specifically for DI. There is no reason to create alternate constructors (especially on controllers, since the only caller is the ControllerFactory which delegates the call to the DI container).
In fact, using multiple constructors with dependency injection is anti-pattern and should be avoided.
Related: Rebuttal: Constructor over-injection anti-pattern
While I agree with other answer by #NightOwl888. In some cases you may want to have multiple constructors.
Have you tried InjectionConstructor attribute?
[InjectionConstructor]
public OrganisationController(IPush pushMessage)
{
_pushMessage = pushMessage;
}
I'm trying to create an instance of an object from a web.config configuration, like this:
<add name="Log4Net" type="Spm.Services.Logging.Log4NetServices.Log4NetReporting, Spm.Services" />
The type Log4NetReporting has a constructor with an argument I want to inject, like this:
public class NLogReporting : ILogReporting
{
[Inject]
public NLogReporting(IRepository<NLogError> nLogRepository)
{
this.nLogRepository = nLogRepository;
}
}
I was trying to create an instance of this object by doing this:
var logger = Activator.CreateInstance(type) as ILogReporting;
But I get an exception saying "No parameterless constructor has been define for this object".
Ideally, I would like to do this using Ninject but I don't know how. My code is separated in different assemblies so the Ninject initialization (look below) is in one assembly (the Web application assembly) and this code is in the Services assembly.
Here's my Ninject initialization code:
private static StandardKernel CreateNinjectKernel()
{
var kernel = new StandardKernel();
RegisterNinjectServices(kernel);
ConfigureAutoMapper(kernel);
return kernel;
}
private static void RegisterNinjectServices(IKernel kernel)
{
kernel.Bind<IRepository<NLogError>>().To<Repository<EntityDbContext, NLogError>>().InRequestScope();
}
Is this possible to do or am I just doing it all wrong?
/Ingo
ideally you would have ILogReporting injected into the service that would use it.
public class SomeService : ISomeService
{
private readonly ILogReporting _logger;
public SomeService(ILogReporting logger)
{
_logger = logger;
}
// .... code....
}
but if you need to request the instance at the time of execution, not creation, then you will need some way to access the DI container (the Ninject Kernel) from wherever you are trying to get the ILogReporting instance. Ninject's WebAPI integration wires its Kernel up to the System.Web.Mvc.IDependencyResolver, so we can use that.
public class SomeService : ISomeService
{
private readonly IDependencyResolver _resolver;
public SomeService(IDependencyResolver resolver)
{
_resolver = resolver;
}
public void Execute()
{
var logger = _resolver.GetService<ILogReporting>();
// .... code....
}
}
In my bootstrapper:
namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
public static class Initializer
{
private static bool isInitialize;
private static readonly object LockObj = new object();
private static IUnityContainer defaultContainer = new UnityContainer();
static Initializer()
{
Initialize();
}
public static void Initialize()
{
if (isInitialize)
return;
lock (LockObj)
{
IUnityContainer container = defaultContainer;
//registering Unity for MVC
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
//registering Unity for web API
// GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
#region managers
container.RegisterType<ISettingsManager, SettingsManager>();
container.RegisterType<IMamDataManager, MamDataManager>();
container.RegisterType<IAppsDataManager, AppsDataManager>();
#endregion
if (!isInitialize)
{
isInitialize = true;
}
}
}
}
}
in my controller's code:
ISettingsManager sm = mUnityContainer.Resolve<ISettingsManager>();
hovering on mUnityContainer I see ISettingsManager is mapped to SettingsManager
but then I get the error:
Exception is: InvalidOperationException - The current type, is an
interface and cannot be constructed. Are you missing a type mapping?
I have also tried
ISettingsManager sm = (ISettingsManager)mUnityContainer.Resolve<>(typeof(ISettingsManager));
but no use
Just for others (like me) who might have faced the above error. The solution in simple terms.
You might have missed to register your Interface and class (which implements that inteface) registration in your code.
e.g if the error is
"The current type, xyznamespace. Imyinterfacename, is an interface and cannot be constructed. Are you missing a type mapping?"
Then you must register the class which implements the Imyinterfacename in the UnityConfig class in the Register method. using code like below
container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
You are incorrectly using Dependency Injection. The proper way is to have your controllers take the dependencies they need and leave to the dependency injection framework inject the concrete instances:
public class HomeController: Controller
{
private readonly ISettingsManager settingsManager;
public HomeController(ISettingsManager settingsManager)
{
this.settingsManager = settingsManager;
}
public ActionResult Index()
{
// you could use the this.settingsManager here
}
}
As you can see in this example the controller doesn't know anything about the container. And that's how it should be.
All the DI wiring should happen in your Bootstraper. You should never use container.Resolve<> calls in your code.
As far as your error is concerned, probably the mUnityContainer you are using inside your controller is not the same instance as the one constructed in your Bootstraper. But since you shouldn't be using any container code in your controllers, this shouldn't be a problem anymore.
In my case, I was getting this error despite registering an existing instance for the interface in question.
Turned out, it was because I was using Unity in WebForms by way of the Unity.WebForms Nuget package, and I had specified a Hierarchical Lifetime manager for the dependency I was providing an instance for, yet a Transient lifetime manager for a subsequent type that depended on the previous type - not usually an issue - but with Unity.WebForms, the lifetime managers work a little differently... your injected types seem to require a Hierarchical lifetime manager, but a new container is still created for every web request (because of the architecture of web forms I guess) as explained excellently in this post.
Anyway, I resolved it by simply not specifying a lifetime manager for the types/instances when registering them.
i.e.
container.RegisterInstance<IMapper>(MappingConfig.GetMapper(), new HierarchicalLifetimeManager());
container.RegisterType<IUserContext, UserContext>(new TransientLifetimeManager());
becomes
container.RegisterInstance<IMapper>(MappingConfig.GetMapper());
container.RegisterType<IUserContext, UserContext>();
So that IMapper can be resolved successfully here:
public class UserContext : BaseContext, IUserContext
{
public UserContext(IMapper _mapper) : base(_mapper)
{
}
...
}
In my case, I have used 2 different context with Unitofwork and Ioc container so i see this problem insistanting while service layer try to make inject second repository to DI. The reason is that exist module has containing other module instance and container supposed to gettng a call from not constractured new repository.. i write here for whome in my shooes
May be You are not registering the Controllers.
Try below code:
Step 1.
Write your own controller factory class
ControllerFactory :DefaultControllerFactory by implementing defaultcontrollerfactory
in models folder
public class ControllerFactory :DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
throw new ArgumentNullException("controllerType");
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(string.Format(
"Type requested is not a controller: {0}",
controllerType.Name),
"controllerType");
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
}
catch
{
return null;
}
}
public static class MvcUnityContainer
{
public static UnityContainer Container { get; set; }
}
}
Step 2:Regigster it in BootStrap:
inBuildUnityContainer method
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
//RegisterTypes(container);
container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>();
MvcUnityContainer.Container = container;
return container;
}
Step 3:
In Global Asax.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Bootstrapper.Initialise();
ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));
}
And you are done
I had this problem, and the cause was that I had not added the Microsoft.Owin.Host.SystemWeb NuGet package to my project. Although the code in my startup class was correct, it was not being executed.
So if you're trying to solve this problem, put a breakpoint in the code where you do the Unity registrations. If you don't hit it, your dependency injection isn't going to work.
Below code will be helpful for you
public static IUnityContainer Initialise(IUnityContainer container = null)
{
if (container == null)
{
container = new UnityContainer();
}
container.RegisterType<ISettingsManager, SettingsManager>();
container.Resolve<SettingsManager>();
container.RegisterType<SettingsManagerController>(new InjectionProperty("_SettingManagerProvider", new ResolvedParameter<ISettingManager>()));
return container;
}
Using an IOC-container like Unity,AutoFac or others you have to Register and Resolve the IInterface to get the instance. This you do in the app class the root of all.
After doing the Register/Resolve stuff I am creating my MainController and pass them ALL resolved Services like:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register<IUserService1, UserService1>();
builder.Register<IUserService2, UserService2>();
builder.Register<IUserService3, UserService3>();
builder.Register<IAnotherService, AnotherService>();
// And many more Services...
_container = builder.Build();
var userService1 = _container.Resolve<IUserService1>();
var userService2 = _container.Resolve<IUserService2>();
var userService3 = _container.Resolve<IUserService3>();
var anotherService = _container.Resolve<IAnotherService>();
var vm = new MainController(userService1,userService2,userService3,anotherService)
}
public class MainController
{
private UserController1 _userVM1;
private UserController2 _userVM2;
private UserController3 _userVM3;
public MainController(IUserService1 userService1,IUserService2 userService2,IUserService3 userService3,anotherService)
{
_userVM1 = new UserController1(userService1,anotherService);
_userVM2 = new UserController2(userService2,...,...);
_userVM3 = new UserController3(userService3,...,...,...);
}
}
// Such a Controller class needs to be created 10 times... and what I do here is typical for all Controllers driving the GUI
public class UserController1
{
private readonly IUserService1 _userService1;
public UserController1(IUserService1 userService1,IAnotherService anotherService)
{
_userService1 = userService1;
//Bind data to GUI
UserData1Collection = ConvertModelIntoViewModelCollection(userService1,anotherService);
}
public ObservableCollection<UserData1> UserData1Collection { get; set; }
private ObservableCollection<UserData1ViewModel> ConvertModelIntoViewModelCollection(IAnotherService anotherService)
{
var userData1ViewModelCollection = new ObservableCollection<UserData1ViewModel>();
_userService1.GetUserData1().ForEach(user =>
{
userData1ViewModelCollection.Add(new UserData1ViewModel(user, anotherService,...));
});
return userData1ViewModelCollection;
}
}
Now the question:
There is a lot of falling through/passing trough services because I have to call services when for example properties of viewmodels change via lost_focus on gui controls.
Is that all right what I do? Do you see any disadvantage? Or how would you do it?
Update
That DI stuff is a massiv attack on my vicious habits :P
Did you meant it that way Can?
Btw. why should I do that controller factory? Why then not a ServiceFactory too... then we are back to the ServiceLocator...
How do I get now that controller instances in my MainViewModel? via extending the Constructor of my MVM with many additional params? ending up with 30 params? ...
protected override void OnStartup(StartupEventArgs e)
{
IContainerBuilder builder = new ContainerBuilder();
// Firstly Register ALL existing Services
builder.Register<IAdminService, AdminService>();
builder.Register<IDocumentService, DocumentService>();
builder.Register<ILessonPlannerService, LessonPlannerService>();
builder.Register<IMediator, Mediator>();
builder.Register<IMainRepository, MainRepository>();
builder.Register<MainViewModel>();
IContainer _container = builder.Build();
// THEN Register ALL Controllers needing the previously registered Services
IControllerFactory factory = new ControllerFactory(builder);
IDailyPlanner controller1 = factory.Create<IDailyPlanner>();
IWeeklyPlanner controller2 = factory.Create<IWeeklyPlanner>();
SchoolclassAdministrationViewModel controller3 = factory.Create<SchoolclassAdministrationViewModel>();
// THEN Register the mainViewModel(MainController) which should take ALL Services and ALL Controller... WOW thats a massive Ctor param count... is that pure? Did you mean it that way???
MainViewModel mainViewModel = _container.Resolve<MainViewModel>();
//MainWindow mainWindow = _container.Resolve<MainWindow>();
//mainWindow.DataContext = mainViewModel;
//mainWindow.ShowDialog();
}
public class ControllerFactory : IControllerFactory
{
private readonly IContainerBuilder _builder;
private readonly IContainer _container;
/// <summary>
/// Takes the IOC container to register all Controllers
/// </summary>
public ControllerFactory(IContainerBuilder builder)
{
_builder = builder;
_builder.Register<SchoolclassAdministrationViewModel>();
_builder.Register<IDailyPlanner, LessonPlannerDailyViewModel>();
_builder.Register<IWeeklyPlanner, LessonPlannerWeeklyViewModel>();
_container = _builder.Build();
}
/// <summary>
/// Returns an Instance of a given Type
/// </summary>
public T Create<T>()
{
return _container.Resolve<T>();
}
}
Update2:
Now I changed my code that the MainViewModel accepts the IControllerFactory as Parameter and added these two lines of code to the App class:
builder.Register<IControllerFactory, ControllerFactory>();
builder.Register<IContainerBuilder, ContainerBuilder>();
That way I dont need to pass all controllers in the MainViewModel Ctor instead the MainViewModel gets the controller instances from the Factory.
Is there anything better I can do here? Or is that an acceptable good solution? I have no experience at all with DI so I ask :)
Update3
OK I did some code refactoring and made comments for others so they understand whats the final solution:
protected override void OnStartup(StartupEventArgs e)
{
IContainerBuilder builder = new ContainerBuilder();
// Firstly Register ALL existing Services
builder.Register<IAdminService, AdminService>();
builder.Register<IDocumentService, DocumentService>();
builder.Register<ILessonPlannerService, LessonPlannerService>();
builder.Register<IMediator, Mediator>();
builder.Register<IMainRepository, MainRepository>();
builder.Register<IControllerFactory, ControllerFactory>();
builder.Register<IDailyPlanner, LessonPlannerDailyViewModel>();
builder.Register<IWeeklyPlanner, LessonPlannerWeeklyViewModel>();
// Just for visual separation THEN register the MainController driving all other Controllers created via the IControllerFactory
builder.Register<MainViewModel>();
// Build the container
IContainer container = builder.Build();
// THEN Register the MainController which should take ALL IServices and the IFactory
MainViewModel mainViewModel = container.Resolve<MainViewModel>();
// LATER in the mainViewModel`s Ctor you can create all 10 Controller instances with the IControllerFactory like this
// _dailyPlannerController = controllerFactory.Create<IDailyPlanner>();
MainWindow mainWindow = new MainWindow();
mainWindow.DataContext = mainViewModel;
mainWindow.ShowDialog();
}
public class ControllerFactory : IControllerFactory
{
private readonly IContainer _container;
/// <summary>
/// Takes the IOC container to resolve all Controllers
/// </summary>
public ControllerFactory(IContainer container)
{
_container = container;
}
/// <summary>
/// Returns an Instance of a given Type
/// </summary>
public T Create<T>()
{
return _container.Resolve<T>();
}
}
Thank you very much for your time, #Can. I have learned a lot!
It seems to me that you have misunderstood how to use an IoC container. Instead of creating instances of your services and passing them as parameters, you need to ask the container to resolve them for you.
For example, you can refactor your code as follows to make use of IoC properly:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register<IUserService1, UserService1>();
builder.Register<IUserService2, UserService2>();
builder.Register<IUserService3, UserService3>();
builder.Register<IAnotherService, AnotherService>();
builder.Register<MainController, MainController>();
// And many more Services...
_container = builder.Build();
//let the container inject all the required dependencies into MainController..
var vm = _container.Resolve<MainController>();
}
The container in this case should control the lifecycle of your MainController object and make sure that all the dependencies (properties and constructor parameters that need to be initialized) are injected and populated.
What will happen is that the container will understand that to create an instance of MainController, it needs IUserService1, IUserService2 and so forth, and in turn will look if it can create any instances of those, by looking at the other types registered with the container. This will be done in a recursive manner to build up a dependency tree until all the dependencies of a class can be satisified. The resulting MainController you get will already have all the dependencies injected in it.
Ideally, you should call Resolve() in as little places as possible in order to structure your application in a way that there is only one root. For an in depth view into Dependency Injection, I strongly recommend the book Dependency Injection in .NET by Mark Seeman, which is in my opinion one of the best introduction to DI one can have.
UPDATE:
The reason why I suggested to use a ControllerFactory was because you had a lot of UserController classes in your MainController, and passing all those as a dependency you would end up with 10+ constructor parameters, not to mention that having to add more when you create new controllers. If your viewmodels only have dependency on one controller, then it doesn't make sense to use the factory in that way and you can have a direct dependency on the required controller.
As for ServiceFactory, it is not needed, because each of your classes are not likely to require ALL the service classes available, just some of them. In that case it is better to specify them explicitly for each service in the constructor.
You should also register all your instances in one place (or in small installer classes) instead of within constructor for different classes.
Here's a question that is more specific to MVVM that should get you going on how to structure your classes and dependencies:
How can I combine MVVM and Dependency Injection in a WPF app?