Comment utiliser Autofac pour injecter une implémentation spécifique dans le constructeur

J’ai deux classes qui prennent un ILastActivityUpdator tant que paramètre de constructeur: UserService et AnonymousUserService .

 public AnonymousUserService(ILastActivityUpdator lastActivityUpdator) { if (lastActivityUpdator == null) { throw new ArgumentNullException("lastActivityUpdator"); } this.lastActivityUpdator = lastActivityUpdator; } 

Et semblable à ci-dessus pour UserService :

 public UserService(ILastActivityUpdator lastActivityUpdator) { if (lastActivityUpdator == null) { throw new ArgumentNullException("lastActivityUpdator"); } this.lastActivityUpdator = lastActivityUpdator; } 

ILastActivityUpdator interface ILastActivityUpdator a une méthode: UpdateLastActivity(int userId) . Il y a deux implémentations de l’interface, un LastActivityUpdator et un décorateur appelé AnonymousUserLastActivityUpdator qui hérite de LastActivityUpdator et ajoute des fonctionnalités supplémentaires à la méthode, comme LastActivityUpdator :

 public class AnonymousUserLastActivityUpdator : LastActivityUpdator, IAnonymousUserLastActivityUpdator { public AnonymousUserLastActivityUpdator() { } public override void UpdateLastActivity(int userId) { base.UpdateLastActivity(userId); // Extra functionality } } 

Je souhaite maintenant utiliser Autofac pour câbler AnonymousUserService avec AnonymousUserLastActivityUpdator et UserService avec LastActivityUpdator .

Ce que j’ai essayé, c’est d’append une interface pour le décorateur qui dérive de l’interface de base, comme ceci:

 public interface IAnonymousUserLastActivityUpdator : ILastActivityUpdator { } 

Ensuite, j’ai pensé que je pouvais utiliser IAnonymousUserLastActivityUpdator dans le constructeur AnonymousUserService et que tout serait correctement câblé automatiquement.

Malheureusement, il utilise toujours la première implémentation, à savoir IAnonymousUserLastActivityUpdator car il est enregistré plus tôt (ordre alphabétique).

Comment faire pour que AnonymousUserService reçoive AnonymousUserLastActivityUpdator et UserService LastActivityUpdator ?

    Autofac est bien documenté et il semble que vous puissiez trouver ce que vous cherchez ici . D’après ce que je peux dire, si vous avez enregistré vos programmes de mise à jour avec

     builder.RegisterType(); builder.RegisterType(); 

    alors vous devriez pouvoir enregistrer vos services avec

     builder.Register(c => new UserService(c.Resolve())); builder.Register(c => new AnonymousUserService(c.Resolve())); 

    ou

     builder.RegisterType().WithParameter( (p, c) => p.ParameterType == typeof(ILastActivityUpdator), (p, c) => c.Resolve()); builder.RegisterType().WithParameter( (p, c) => p.ParameterType == typeof(ILastActivityUpdator), (p, c) => c.Resolve()); 

    Ensuite, lorsque vous résolvez UserService ou AnonymousUserService partir du conteneur, ils obtiennent les dépendances appropriées.

    En passant, si une interface est injectée dans une classe, cette classe devrait alors fonctionner correctement avec toutes les implémentations de cette interface ( LSP ). D’après les noms de classe, AnonymousUserService ne fonctionne qu’avec AnonymousUserLastActivityUpdator et non avec une implémentation de ILastActivityUpdator . Si tel est le cas, il peut être approprié d’introduire une abstraction différente (telle que IAnonymousUserLastActivityUpdator ), comme vous l’avez suggéré.