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<>));
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