La respuesta corta es: No, de fábrica debe tener el tipo.
Usted debe tener el tipo porque, técnicamente hablando, se puede registrar dos servicios nombrados diferentes con diferentes tipos:
builder.RegisterInstance(someObject).Named<IFoo>("name-here");
builder.RegisterInstance(someOtherObject).Named<IBar>("name-here");
Sin el tipo, podrás especie de "obtener lo que se obtiene" Si sabes a lo que me refiero. No será predecible.
No hay una forma oficialmente compatible para obtener lo que está buscando, pero puede tal vez hackear una solución. Algo como esto:
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>());
}
Sin embargo, no puedo realmente recomiendo hacer eso. Una de las cosas que hace que Autofac sea flexible es la capacidad de tener "fuentes de registro" que pueden hacer algunas cosas interesantes con límite de tiempo. Cuando se resuelve un servicio "de la manera correcta" hay una inicialización y escaneo que continúa para asegurarse de que todo lo que se debe registrar dinámicamente se registre dinámicamente. Cuando accede a la lista de registros en el registro de componentes, es la lista de todo lo que está registrado hasta ese punto, que puede no contener el servicio nombrado que está buscando ... en cuyo caso fallará la resolución cuando de lo contrario no podría.
Si no está utilizando ninguna de las funciones dinámicas de registro en su aplicación, probablemente esté seguro. Solo ten en cuenta que estás dando vueltas por el costado con algo como esto y es posible que no obtengas los resultados esperados. Si/cuando cosas raras comienzan a suceder, ha sido advertido.
Si desea registrar y resolver los servicios sin tipo "de la manera correcta", es probable que deba implementar su propio Autofac.Core.Service. Los registros con clave/nombre son Autofac.Core.KeyedService pero siempre tienen un tipo asociado; su personalizado no debería ser escrito. A continuación, había necesidad de poner en práctica sus propias extensiones de registro en el ContainerBuilder tal manera que usted puede hacer algo como:
builder.RegisterUntypedNamed(someObject, "name-here");
... y luego también se necesitaría una extensión correspondiente en IComponentContext para resolver el tipo de servicio por lo que podría hacer correctamente:
container.ResolveUntypedNamed("name-here");
... mientras participan en todas las cosas de registro/escaneo de enlace en tiempo que pasa detrás de las escenas.
Gracias por la respuesta extremadamente minuciosa. La razón por la que estoy preguntando es porque estoy usando la propiedad de dependencia Bind.Model de Caliburn Micro. Caliburn utiliza el valor proporcionado a esa propiedad como una clave para resolver ViewModel desde el contenedor DI. El tipo no se pasa. Lo que hice fue establecer Bind.Model = y luego Type.GetType (nombre completo).Con el tipo, puedo ir a Autofac. –