2

J'ai lu l'article suivant .NET Junkie - Meanwhile... on the command side of my architecture qui a été suggéré par un autre utilisateur de stackoverflow qui décrit le modèle de commande et fournit une stratégie pour l'utiliser avec DI à la fin de l'article.modèle de commande utilisant Dependency Injection pour le contrôleur MVC 3

Cela a énormément aidé, mais la seule chose qui me manque, disons que je crée une nouvelle classe appelée CheckoutCustomerCommandHandler.

Maintenant, disons que j'ai besoin d'injecter cette commande et le MoveCustomerCommandHandler dans un contrôleur pour une raison quelconque via le constructeur. Comment cela affecte-t-il l'installation du conteneur DI et le constructeur?

À la base, ils implémentent tous les deux la même interface. Il semble que cela entraînerait un problème de recherche pour le conteneur DI. Dans l'exemple de l'article, voici la configuration de leur injecteur d'échantillon:

public interface ICommandHandler<TCommand> 
{ 
    void Handle(TCommand command); 
} 

// Exactly the same as before, but now with the interface. 
public class MoveCustomerCommandHandler 
: ICommandHandler<MoveCustomerCommand> 
{ 
    private readonly UnitOfWork db; 

    public MoveCustomerCommandHandler(UnitOfWork db, 
    [Other dependencies here]) 
    { 
     this.db = db; 
    } 

    public void Handle(MoveCustomerCommand command) 
    { 
     // TODO: Logic here 
    } 
} 

// Again, same implementation as before, but now we depend 
// upon the ICommandHandler abstraction. 
public class CustomerController : Controller 
{ 
    private ICommandHandler<MoveCustomerCommand> handler; 

    public CustomerController(
    ICommandHandler<MoveCustomerCommand> handler) 
    { 
     this.handler = handler; 
    } 

    public void MoveCustomer(int customerId, 
     Address newAddress) 
    { 
     var command = new MoveCustomerCommand 
     { 
      CustomerId = customerId, 
      NewAddress = newAddress 
     }; 

     this.handler.Handle(command); 
    } 
} 

using SimpleInjector; 
using SimpleInjector.Extensions; 

var container = new Container(); 

// Go look in all assemblies and register all implementations 
// of ICommandHandler<T> by their closed interface: 
container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>), 
    AppDomain.CurrentDomain.GetAssemblies()); 

// Decorate each returned ICommandHandler<T> object with 
// a TransactionCommandHandlerDecorator<T>. 
container.RegisterDecorator(typeof(ICommandHandler<>), 
    typeof(TransactionCommandHandlerDecorator<>)); 

// Decorate each returned ICommandHandler<T> object with 
// a DeadlockRetryCommandHandlerDecorator<T>. 
container.RegisterDecorator(typeof(ICommandHandler<>), 
    typeof(DeadlockRetryCommandHandlerDecorator<>)); 
+0

Il semble que ce soit une question spécifique 'SimpleInjector'. Je peux vous dire que d'autres conteneurs DI comme Ninject et Autofac supportent ce scénario. – neontapir

Répondre

3

Voici ce que vos déclarations de classe ressembleraient ...

public class CheckoutCustomerCommandHandler : 
    ICommandHandler<CheckoutCustomerCommand> {...} 

public class MoveCustomerCommandHandler : 
    ICommandHandler<MoveCustomerCommand> {...} 

Ceux-ci peuvent ressembler ils mettent en œuvre la même interface, mais en fait compiler à deux interfaces différentes parce que les arguments génériques sont différents. Votre cadre DI sera en mesure de les distinguer.

+0

Merci. Ma crainte était que cela présenterait un énorme problème. Savez-vous si cela fonctionnera avec le bloc d'application de l'unité? – user1790300

+1

Unity n'aura aucun problème à résoudre votre implémentation du "type générique fermé". Le problème que vous rencontrerez probablement est de savoir comment enregistrer les décorateurs car il n'y a pas d'équivalent à RegisterDecorator. Cet article sur le [Unity Interception Extension] (http://www.lm-tech.it/Blog/post/2011/10/18/How-to-use-the-Unity-Interception-Extension.aspx) pourrait être utile à cette étape. – TylerOhlsen

+0

Merci. Vérification de l'article maintenant. – user1790300

Questions connexes