我正在尝试创建一个Orchard CMS模块,该模块使用OpenRasta为给定路径启用RESTful Web服务(例如/ openrasta / *)。
我需要到Orchard ContentManager获取要返回的服务的内容,因此我的OpenRasta处理程序(ContentHandler)使用ContentService,它实现继承IDependency的IContentService。通常这会起作用,因为Orchard会将ContentManager注入构造函数:
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:无法解析类型 ContentService,因为其依赖项无法完成 构造函数:Orchard.ContentManagement.IContentManager
有没有办法实现这一点,我可以去某个地方的Orchard课并说“给我一个ContentManager实例”吗?
更新:请参阅我对@ rfcdejong关于我的进展更新的回答的评论。
答案 0 :(得分:4)
您是否正在使用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?你可能需要解析界面。
我想你想要以下工作:
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>();
答案 1 :(得分:1)
所以问题是您的CMS使用自己的IoC容器。默认情况下,OpenRasta也会这样做。
这意味着OpenRasta将无法看到Orchard中存在的服务。
对于所有其他IoC容器,答案很简单:您使用IoC适配层,让OpenRasta可以在您想要的任何ioc容器中运行。我们支持团结,结构图,城堡和ninject。也就是说,不支持autofac,因为没有人建立它。
解决此问题的最简洁方法(以及将来可能遇到的任何其他问题)将是为openrasta构建自己的autofac ioc适配层。如果您需要帮助,可以加入openeverything邮件列表,开发人员乐意为您提供帮助。