Можно ли разрешить экземпляр из Autofac, учитывая только ключ строки? - PullRequest
5 голосов
/ 02 февраля 2012

Используя Autofac, возможно ли это сделать?У меня нет типа экземпляра.

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

Из какого-то поиска в Google это кажется невозможным, но я хотел быть уверен.*

1 Ответ

8 голосов
/ 03 февраля 2012

Краткий ответ: нет, из коробки вы должны иметь тип.

Вы должны иметь тип, потому что, технически говоря, вы можете зарегистрировать две разные названные службыс разными типами:

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");

... при этом участвуя во всех вещах с поздней регистрацией / сканированием, которые происходят за кулисами.

...