我们有一个用 Nancy(和 TinyIoc)实现的 ASP.NET REST 服务,它与一个相当大的遗留应用程序交互。我们想过渡到完全依赖注入(inject)。目前,我们的大多数模块直接实例化 Controller ,并采用一个上下文类,该类使用 NancyContext Context
属性保存请求信息。像这样:
public FooModule(ILegacyService legacyService) {
Get["/"] = parameters => new FooController(new RequestContext(Context), legacyService).GetFoo();
}
我们想直接在模块中注入(inject) Controller ,并让 super-duper-happy-path 处理所有事情:)
我们的问题都源于我们需要来自NancyContext
的信息。 url、 header 等。所以我们尝试了各种方法来实现依赖注入(inject)必杀技。
尝试注入(inject) Controller 失败,因为它们是在应用程序范围内实例化的,因此任何对 RequestContext
的依赖都不会有当前的上下文信息。即使在 ConfigureRequestContainer
中注册 RequestContext
也不会波及到所有依赖项,它们会保留对过时的 RequestContext
的引用。
我们尝试使用 IRequestStartup
属性注入(inject)上下文,这似乎很成功,直到我们遇到并发问题。不同线程中的同时请求将覆盖应用程序范围 RequestContext
。
我们发现我们可以在 ConfigureRequestContainer
中调用 container.AutoRegister()
,但这会导致严重的延迟,因为注册需要几秒钟的时间来处理我们拥有的类型.
在 ConfigureApplicationContainer
中使用 AsPerRequestSingleton()
似乎会注册一次,然后根据请求实例化,但似乎没有办法获得自动注册坚持这一点。
看来我们需要手动注册所有类型,并手动更新此配置。是这样吗?我们真的更希望在每个请求生命周期内进行某种类型的自动注册。
我创建了一个小型测试项目 ( https://github.com/Rassi/NancyIocTest ),我在其中尝试了其中的一些解决方案。
最佳答案
使用 DefaultNancyAspNetBootstrapper,您可以像这样创建自己的自动注册:
public class Bootstrapper : DefaultNancyAspNetBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
var assemblyClasses = Assembly.GetExecutingAssembly().GetTypes().Where(type => type.IsClass);
foreach (var assemblyClass in assemblyClasses)
{
var interfaces = assemblyClass.GetInterfaces();
if (interfaces.Count() == 1)
{
container.Register(interfaces[0], assemblyClass).AsPerRequestSingleton();
}
}
}
然后根据请求实例化所有内容,您可以使用 RequestStartup()
注入(inject)上下文信息:
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
base.RequestStartup(container, pipelines, context);
var requestUrl = container.Resolve<IRequestUrl>();
requestUrl.Context = context;
}
}
这是一个简单的概念证明,它将找到实现一个接口(interface)的类,并将其注册到该接口(interface)。可能应该处理几个问题,例如:注册实现多个接口(interface)的类(可能使用将 Name 注册到 IName 的约定)。并且还处理注册相同接口(interface)的多个类。
关于c# - Nancy IoC 每个请求自动注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32247469/