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é.