我正在尝试创建一个 Orchard CMS 模块,该模块可以使用 OpenRasta 为给定路由(例如/openrasta/*)启用 RESTful Web 服务。
我需要访问 Orchard ContentManager 来获取服务返回的内容,因此我的 OpenRasta 处理程序 (ContentHandler) 使用 ContentService,它实现 IContentService,它继承 IDependency。通常这会起作用,因为 Orchard 会将 ContentManager 注入(inject)到构造函数中:
public class ContentService : IContentService {
public IContentManager content;
public ContentService(IContentManager content) {
this.content = content;
}
public IEnumerable<string> GetContentTypeDefinitionNames() {
return content.GetContentTypeDefinitions().Select(d => d.Name);
}
}
但是当我运行它时,我收到一个错误,因为 OpenRasta 不知道有关 Orchard 依赖项的任何信息,并且它尝试创建 ContentService,而不是 Orchard,这很公平:
OpenRasta.DI.DependencyResolutionException: Could not resolve type ContentService because its dependencies couldn't be fullfilled Constructor: Orchard.ContentManagement.IContentManager
有没有办法实现这一点,我可以去某个 Orchard 类并说“给我一个 ContentManager 的实例”吗?
更新:请参阅我对 @rfcdejong 的回答的评论,了解我的进展更新。
最佳答案
您是否使用 ServiceRoute,添加到实现 IRouteProvider 的类中 查看 ServiceRoute 摘要,它显示“启用通过 HTTP 创建服务路由以支持 REST 方案。”
public class Routes : IRouteProvider
{
public void GetRoutes(ICollection<RouteDescriptor> routes)
{
foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor);
}
private static ServiceRoute _rastaService = new ServiceRoute(
"openrasta",
new MyServiceHostFactory<IOpenRastaService>(),
typeof(IOpenRastaService));
public IEnumerable<RouteDescriptor> GetRoutes()
{
return new[]
{
new RouteDescriptor
{
Priority = -1,
Route = _rastaService
}
};
}
}
并且想要解析ContentService?您可能必须解析接口(interface)。
我猜你希望以下内容起作用:
var contentService = LifetimeScope.ResolveNew<IContentService>();
我直接使用了 HostContainer.Resolve,也遇到了问题。我将描述我目前在我自己的 ServiceHostFactory 中使用的解决方案
您有自己的从 OrchardServiceHostFactory 派生的 ServiceHostFactory 吗? 在这种情况下,您可以实现以下代码来帮助您解决实例
private ILifetimeScope _lifetimeScope = null;
private ILifetimeScope LifetimeScope
{
get
{
if (_lifetimeScope == null)
{
IHttpContextAccessor accessor = HostContainer.Resolve<IHttpContextAccessor>();
IRunningShellTable runningShellTable = HostContainer.Resolve<IRunningShellTable>();
ShellSettings shellSettings = runningShellTable.Match(accessor.Current());
IOrchardHost orchardHost = HostContainer.Resolve<IOrchardHost>();
ShellContext shellContext = orchardHost.GetShellContext(shellSettings);
_lifetimeScope = shellContext.LifetimeScope;
}
return _lifetimeScope;
}
}
我还创建了具有以下代码的 LifetimeScopeExtensions
public static class LifetimeScopeExtensions
{
public static T ResolveNew<T>(this ILifetimeScope scope)
{
IWorkContextAccessor workContextAccessor = scope.Resolve<IWorkContextAccessor>();
WorkContext workContext = workContextAccessor.GetContext();
if (workContext == null)
{
using (IWorkContextScope workContextScope = workContextAccessor.CreateWorkContextScope())
{
ILifetimeScope lifetimeScope = workContextScope.Resolve<ILifetimeScope>();
return lifetimeScope.Resolve<T>();
}
}
else
{
ILifetimeScope lifetimeScope = workContext.Resolve<ILifetimeScope>();
return lifetimeScope.Resolve<T>();
}
}
public static object ResolveNew(this ILifetimeScope scope, Type type)
{
IWorkContextAccessor workContextAccessor = scope.Resolve<IWorkContextAccessor>();
WorkContext workContext = workContextAccessor.GetContext();
if (workContext == null)
{
using (IWorkContextScope workContextScope = workContextAccessor.CreateWorkContextScope())
{
ILifetimeScope lifetimeScope = workContextScope.Resolve<ILifetimeScope>();
return lifetimeScope.Resolve(type);
}
}
else
{
ILifetimeScope lifetimeScope = workContext.Resolve<ILifetimeScope>();
return lifetimeScope.Resolve(type);
}
}
}
var settingsService = LifetimeScope.ResolveNew<ITokenServiceSettingsService>();
关于dependency-injection - Orchard CMS : Creating module for OpenRasta, 依赖注入(inject)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9393014/