是否可以从Autofac中解析一个实例,只给出一个字符串键?

ck.*_*ck. 5 autofac

使用Autofac,可以这样做吗?我没有实例的类型.

var instance = container.Resolve("someStringKey");
Run Code Online (Sandbox Code Playgroud)

从一些谷歌搜索,似乎不可能,但我想确定.

谢谢.

Tra*_*lig 8

简短的回答是:不,开箱即用你必须有类型.

应该有类型,因为从技术上讲,你可以注册两种不同类型的命名服务:

builder.RegisterInstance(someObject).Named<IFoo>("name-here");
builder.RegisterInstance(someOtherObject).Named<IBar>("name-here");
Run Code Online (Sandbox Code Playgroud)

如果你知道我的意思,如果没有这种类型,你就会"得到你得到的东西".这是不可预测的.

没有官方支持的方式来获得您正在寻找的东西,但您可能会破解自己的解决方案.像这样的东西:

public static object ResolveUntypedNamed(
  this IComponentContext context,
  string serviceName)
{
  var component = context.ComponentRegistry.Registrations
    .Where(r => r.Services.OfType<KeyedService>()
      .Any(s => s.ServiceKey.Equals(serviceName)))
    .FirstOrDefault();
  return context.ResolveComponent(component, Enumerable.Empty<Parameter>());
}
Run Code Online (Sandbox Code Playgroud)

但是,我不能真的推荐这样做.使Autofac变得灵活的一个原因是能够拥有"注册源",可以做一些有趣的后期事情.当您以"正确的方式"解析服务时,会进行一些初始化和扫描,以确保需要动态注册的所有内容实际上都是动态注册的.当您访问组件注册表上的注册列表时,它是已注册到该点的所有内容的列表,其中可能不包含您正在查找的命名服务...在这种情况下,当您执行时,您将无法通过解析否则可能不会.

如果您没有在应用中使用任何动态注册资料,那么您可能会安全.请注意,你有点像这样的事情,你可能无法获得预期的结果.如果/当奇怪的事情开始发生时,你已经被警告了.

如果您想"以正确的方式"注册和解析无类型服务,您可能需要实现自己的Autofac.Core.Service.键控/命名注册是Autofac.Core.KeyedService,但它们始终具有关联的类型; 您的自定义将不需要键入.然后,您需要在ContainerBuilder上实现自己的注册扩展,以便您可以执行以下操作:

builder.RegisterUntypedNamed(someObject, "name-here");
Run Code Online (Sandbox Code Playgroud)

...然后你还需要IComponentContext上的相应扩展来解析你的服务类型,这样你才能正确地做到:

container.ResolveUntypedNamed("name-here");
Run Code Online (Sandbox Code Playgroud)

...同时仍然参与幕后发布的所有后期注册/扫描内容.