如何在带有 AutoFac 的 Umbraco 7 控制器中通过依赖注入使用 IMediator (MediatR)?
How to use IMediator (MediatR) via dependency injection in Umbraco 7 controller with AutoFac?
我已经根据以下示例为我的 umbracp 7.15.3 应用程序使用 Autofac
设置了依赖注入:https://gosudev.com/blog/software-development/umbraco-cms/umbraco-web-api-and-mvc-dependency-injection-with-autofac/
该示例与示例控制器配合得很好,就像这里一样:https://github.com/gosudev/UmbracoCMSDIMixedMode/blob/master/src/UmbracoCMSDIMixedMode/UmbracoCMSDIMixedMode.Web/Controllers/Api/SampleWebApiController.cs
我需要使用其他服务并且正在尝试使用 IMediator
(MediatR
) 所以我将上面的控制器修改为:
public class SampleWebApiController : UmbracoApiController
{
private readonly IMediator _mediator;
private readonly ISampleService _sampleService;
public SampleWebApiController(ISampleService sampleService, IMediator mediator)
{
_sampleService = sampleService;
}
//http://localhost:60580/umbraco/api/SampleWebApi/Get
[System.Web.Http.HttpGet]
public JsonResult Get()
{
return new JsonResult() { Data = new { items = _sampleService.GetItems() }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
和WebModule
(https://github.com/gosudev/UmbracoCMSDIMixedMode/blob/master/src/UmbracoCMSDIMixedMode/UmbracoCMSDIMixedMode.Web/WebModule.cs)到:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SampleService>().As<ISampleService>();
builder.RegisterType<Mediator>().As<IMediator>();
builder.Register(c => UmbracoContext.Current).AsSelf();
}
此时控制器停止工作,我收到一条错误消息:
{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'SampleWebApiController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "An exception was thrown while activating MyDomain.Controllers.SampleWebApiController -> MediatR.Mediator.",
"ExceptionType": "Autofac.Core.DependencyResolutionException",
"StackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)\r\n at Autofac.Core.Resolving.InstanceLookup.Execute()\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)\r\n at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)\r\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)\r\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)\r\n at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) in C:\projects\autofac-webapi\src\Autofac.Integration.WebApi\AutofacWebApiDependencyScope.cs:line 76\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MediatR.Mediator' can be invoked with the available services and parameters:\r\nCannot resolve parameter 'Microsoft.Practices.ServiceLocation.ServiceLocatorProvider serviceLocatorProvider' of constructor 'Void .ctor(Microsoft.Practices.ServiceLocation.ServiceLocatorProvider)'.",
"ExceptionType": "Autofac.Core.DependencyResolutionException",
"StackTrace": " at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)\r\n at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)"
}
}
}
为什么会出错以及如何将另一个服务注入到这个控制器和可能的其他控制器中?
我已经安装了 MediatR.Extensions.Autofac.DependencyInjection
并更改了这一行:
builder.RegisterType<Mediator>().As<IMediator>();
到
builder.AddMediatR(this.GetType().Assembly);
所以配置是:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SampleService>().As<ISampleService>();
builder.AddMediatR(this.GetType().Assembly); //builder.RegisterType<Mediator>().As<IMediator>();
builder.Register(c => UmbracoContext.Current).AsSelf();
}
我已经根据以下示例为我的 umbracp 7.15.3 应用程序使用 Autofac
设置了依赖注入:https://gosudev.com/blog/software-development/umbraco-cms/umbraco-web-api-and-mvc-dependency-injection-with-autofac/
该示例与示例控制器配合得很好,就像这里一样:https://github.com/gosudev/UmbracoCMSDIMixedMode/blob/master/src/UmbracoCMSDIMixedMode/UmbracoCMSDIMixedMode.Web/Controllers/Api/SampleWebApiController.cs
我需要使用其他服务并且正在尝试使用 IMediator
(MediatR
) 所以我将上面的控制器修改为:
public class SampleWebApiController : UmbracoApiController
{
private readonly IMediator _mediator;
private readonly ISampleService _sampleService;
public SampleWebApiController(ISampleService sampleService, IMediator mediator)
{
_sampleService = sampleService;
}
//http://localhost:60580/umbraco/api/SampleWebApi/Get
[System.Web.Http.HttpGet]
public JsonResult Get()
{
return new JsonResult() { Data = new { items = _sampleService.GetItems() }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
和WebModule
(https://github.com/gosudev/UmbracoCMSDIMixedMode/blob/master/src/UmbracoCMSDIMixedMode/UmbracoCMSDIMixedMode.Web/WebModule.cs)到:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SampleService>().As<ISampleService>();
builder.RegisterType<Mediator>().As<IMediator>();
builder.Register(c => UmbracoContext.Current).AsSelf();
}
此时控制器停止工作,我收到一条错误消息:
{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'SampleWebApiController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "An exception was thrown while activating MyDomain.Controllers.SampleWebApiController -> MediatR.Mediator.",
"ExceptionType": "Autofac.Core.DependencyResolutionException",
"StackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)\r\n at Autofac.Core.Resolving.InstanceLookup.Execute()\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)\r\n at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)\r\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)\r\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)\r\n at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) in C:\projects\autofac-webapi\src\Autofac.Integration.WebApi\AutofacWebApiDependencyScope.cs:line 76\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MediatR.Mediator' can be invoked with the available services and parameters:\r\nCannot resolve parameter 'Microsoft.Practices.ServiceLocation.ServiceLocatorProvider serviceLocatorProvider' of constructor 'Void .ctor(Microsoft.Practices.ServiceLocation.ServiceLocatorProvider)'.",
"ExceptionType": "Autofac.Core.DependencyResolutionException",
"StackTrace": " at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)\r\n at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)"
}
}
}
为什么会出错以及如何将另一个服务注入到这个控制器和可能的其他控制器中?
我已经安装了 MediatR.Extensions.Autofac.DependencyInjection
并更改了这一行:
builder.RegisterType<Mediator>().As<IMediator>();
到
builder.AddMediatR(this.GetType().Assembly);
所以配置是:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SampleService>().As<ISampleService>();
builder.AddMediatR(this.GetType().Assembly); //builder.RegisterType<Mediator>().As<IMediator>();
builder.Register(c => UmbracoContext.Current).AsSelf();
}