Castle Windsor 可以从动态程序集中注册类型吗?

rca*_*ton 1 c# castle-windsor

我有一个使用 Reflection.Emit 创建的动态生成的程序集。然后,我尝试通过以下方式使用 Windsor 从该程序集中注册控制器类型:

WindsorContainer.Register(Classes.FromAssembly(myDynamicAssembly).BasedOn<ApiController>().LifestylePerWebRequest());

当我尝试导航到这些控制器之一中指定的端点时,出现以下错误:

[NotSupportedException: The invoked member is not supported in a dynamic assembly.]
System.Reflection.Emit.InternalAssemblyBuilder.GetExportedTypes() +68
Castle.Core.Internal.ReflectionUtil.GetAvailableTypes(Assembly assembly, Boolean includeNonExported) +74
Castle.MicroKernel.Registration.FromAssemblyDescriptor.&lt;SelectedTypes&gt;b__0(Assembly a) +21
System.Linq.&lt;SelectManyIterator&gt;d__14`2.MoveNext() +267
Castle.MicroKernel.Registration.FromDescriptor.Castle.MicroKernel.Registration.IRegistration.Register(IKernelInternal kernel) +296
Castle.MicroKernel.DefaultKernel.Register(IRegistration[] registrations) +72
Castle.Windsor.WindsorContainer.Register(IRegistration[] registrations) +50
Run Code Online (Sandbox Code Playgroud)

是否无法在动态程序集中注册任何内容,或者是否存在我遗漏的其他问题?

请注意,如果没有 Windsor(即使用默认的控制器激活器服务),程序集/控制器/端点可以正常工作。我可以使用 Windsor 的 DynamicProxy 功能而不是 Reflection.Emit 方法,但在解决这个有点令人畏惧的任务之前,我想用当前方法穷尽所有可能性!

Krz*_*mic 5

不,你没有错过任何东西。目前,Windsor 不支持此功能。

正如堆栈跟踪所示,Classes.FromAssembly(myDynamicAssembly)Windsor 用于Assembly.GetExportedTypes查找要注册的类型,并且如文档所述,动态程序集不支持此方法。

温莎使用GetExportedTypes不必浪费时间查看非公共类,因为它默认只允许注册公共类。

但是,您可以通过添加. IncludeNonPublicTypes()不使用的内容来覆盖它Assembly.GetExportedTypes,并将阻止异常发生。这样做的副作用是,现在 Windsor 将注册任何满足您指定条件的潜在非公共类(BasedOn<ApiController>()因此,如果您想避免这种情况,则必须自己过滤掉这些类。

因此,为了完整起见,您的注册如下所示:

container.Register(
   Classes.FromAssembly(myDynamicAssembly)
      .IncludeNonPublicTypes()
      .BasedOn<ApiController>()
      .LifestylePerWebRequest());
Run Code Online (Sandbox Code Playgroud)

我想 Windsor 没有充分的理由不应该处理开箱即用的动态程序集,所以也许您想为它打开一个问题并在拉取请求中进行破解?