2017-10-20 23 views
1

J'ai besoin que ce service IS soit réutilisable. Chaque fois que IService est injecté dans un constructeur, j'ai besoin de Service.Dependent pour référencer le type de la classe injectée.Obtention d'une référence à un service dépendant avec le type générique

builder.Register<Service>(c => 
     { 
      var a = new Service(); 
      a.Dependent = c.Resolve<CallingType??>(TypedParameter.From(a)); 
      return a; 
     }).As<IService>(); 

interface IService {} 

class Service : IService { 
    BaseClass Dependent {get; set;} 
} 


class SomeClass : BaseClass { 
    SomeClass(IService service) { 
     service.Dependent //This should be type BaseClass of SomeClass 
    } 
} 

Répondre

2

Autofac soutient open generic registration et circular dependencies.
Il peut se faire comme:

builder.RegisterGeneric(typeof (Service<>)) 
    .As(typeof (IService<>)) 
    .InstancePerLifetimeScope() 
    .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); 
builder.RegisterType<SomeClass>() 
    .InstancePerLifetimeScope(); 

Et container.Resolve<IService<SomeClass>>() retournera vous avec le service par exemple injecté SomeClass qui recevra cette Service instance récursive.

On dirait qu'il n'y a pas d'option pour extraire le type d'appelé pendant l'enregistrement. Pour votre exemple mis à jour personnalisé Registration Source peut vous être utile.
C'est un enregistrement "générique" hérité de BaseType types. Mais cela ressemble à une sur-ingénierie.

public class HandlerRegistrationSource : IRegistrationSource 
{ 
    public IEnumerable<IComponentRegistration> RegistrationsFor(
    Service service, 
    Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) 
    { 
    var swt = service as IServiceWithType; 
    if(swt == null || !typeof(BaseClass).IsAssignableFrom(swt.ServiceType)) 
    { 
     // It's not a request for the BaseClass type, so skip it. 
     return Enumerable.Empty<IComponentRegistration>(); 
    }   
    var registration = new ComponentRegistration(
     Guid.NewGuid(), 
     new DelegateActivator(swt.ServiceType, (c, p) => 
     { 
      var myService = c.Resolve<IService>(); 
      ... 
     } 
     ... 
    } 
    ... 
} 
+0

Est-il possible de le faire dans mon exemple mis à jour. Est-ce que autofac a un moyen d'utiliser la réflexion lors de l'enregistrement pour référencer le type d'appel? –

+0

@CodyBouche, j'ai mis à jour ma réponse. – Kote