仅给出字符串键是否可以从 Autofac 解析实例?

发布于 2025-01-02 15:48:24 字数 159 浏览 0 评论 0原文

使用 Autofac 可以做到这一点吗?我没有实例的类型。

var instance = container.Resolve("someStringKey");

从一些谷歌搜索来看,这似乎不可能,但我想确定一下。

谢谢。

Using Autofac, is it possible to do this? I don't have the type of the instance.

var instance = container.Resolve("someStringKey");

From some Googling, it doesn't seem to be possible, but I wanted to be sure.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的旅程 2025-01-09 15:48:24

简短的回答是:不,您必须拥有开箱即用的类型。

应该拥有该类型,因为从技术上讲,您可以使用不同的类型注册两个不同的命名服务:

builder.RegisterInstance(someObject).Named<IFoo>("name-here");
builder.RegisterInstance(someOtherObject).Named<IBar>("name-here");

如果没有该类型,您将有点“得到你得到的”,如果你明白我的意思。这将是不可预测的。

没有官方支持的方法来获取您正在寻找的内容,但是您也许可以自己找到一个解决方案。像这样的事情:

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>());
}

但是,我真的不建议这样做。 使 Autofac 变得灵活的原因之一是能够拥有“注册源”,可以执行一些有趣的后期绑定操作。当您以“正确的方式”解析服务时,会进行一些初始化和扫描,以确保需要动态注册的所有内容实际上都得到动态注册。当您访问组件注册表上的注册列表时,它是截至该点注册的所有内容的列表,其中可能不包含您正在查找的命名服务...在这种情况下,您如果你不这样做,你的解决方案就会失败。

如果您没有在应用程序中使用任何动态注册内容,那么您可能是安全的。请注意,您可能会在类似的事情上绕来绕去,并且可能无法获得预期的结果。如果/当奇怪的事情开始发生时,您已收到警告

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

builder.RegisterUntypedNamed(someObject, "name-here");

...然后您还需要 IComponentContext 上的相应扩展来解析您的服务类型,以便您可以正确执行:

container.ResolveUntypedNamed("name-here");

.. .同时仍然参与幕后进行的所有后期绑定注册/扫描工作。

The short answer is: No, out of the box you have to have the type.

You should have the type because, technically speaking, you can register two different named services with different types:

builder.RegisterInstance(someObject).Named<IFoo>("name-here");
builder.RegisterInstance(someOtherObject).Named<IBar>("name-here");

Without the type, you'll sort of "get what you get," if you know what I mean. It won't be predictable.

There is no officially supported way to get what you're looking for, but you can maybe hack yourself a solution. Something like this:

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>());
}

However, I can't really recommend doing that. One of the things that makes Autofac flexible is the ability to have "registration sources" that can do some interesting late-bound things. When you resolve a service "the right way" there's some initialization and scanning that goes on to make sure everything that needs to be dynamically registered actually gets dynamically registered. When you access the list of registrations on the component registry, it's the list of everything that's registered up to that point, which may not contain the named service you're looking for... in which case you'll fail the resolution when you otherwise might not.

If you're not using any of the dynamic registration stuff in your app, you're probably safe. Just be aware that you are sort of going around-the-side with something like this and you may not get the expected results. If/when weird things start happening, you've been warned.

If you want to register and resolve untyped services "the right way," you probably will need to implement your own Autofac.Core.Service. Keyed/named registrations are Autofac.Core.KeyedService but they always have a type associated; your custom one would need to not be typed. You'd then need to implement your own registration extensions on the ContainerBuilder such that you can do something like:

builder.RegisterUntypedNamed(someObject, "name-here");

...and then you'd also need a corresponding extension on IComponentContext to resolve your service type so you could correctly do:

container.ResolveUntypedNamed("name-here");

...while still participating in all of the late-bound registration/scanning stuff that goes on behind the scenes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文