이유를 이해 한 이유는 다음과 같습니다. 동일한 인터페이스에 대해 데이터를 변경하는 작업을 처리하고 싶습니다. ICommand ICommandHandlers 그 명령은 내가 원하는 명령을 처리합니다. 그래서 CreatePersonCommand를 원한다면 CreatePersonCommandHandler가 필요합니다. SimpleInjector 항상 내가 가지고있는 CreateBaseCommand<>
에 대한 DeleteCommandHandler<>
를 해결하려고 어떤 이유 그래서RegisterInpenGeneric with SimpleInjector가 잘못된 유형을 해결합니다.
// The e.g. CreatePersonCommand, with TResult being Person, as an example.
public interface ICommand<TResult>
{
}
//This handles the command, so CreatePersonCommandHandler
public interface ICommandHandler<in TCommand, out TResult>
where TCommand : ICommand<TResult>
{
TResult Handle(TCommand command);
}
// Imagine a generic CRUD set of operations here where we pass
// in an instance of what we need made
public class CreateBaseCommand<TModel> : ICommand<TModel>
{
public TModel ItemToCreate { get; set; }
}
public class DeleteBaseCommand<TModel> : ICommand<TModel>
{
public TModel ItemToDelete { get; set; }
}
public class CreateCommandBaseHandler<TModel>
: ICommandHandler<CreateBaseCommand<TModel>, TModel>
{
public TModel Handle(CreateBaseCommand<TModel> command)
{
// create the thing
return default (TModel);
}
}
public class DeleteCommandBaseHandler<TModel>
: ICommandHandler<DeleteBaseCommand<TModel>, TModel>
{
public TModel Handle(DeleteBaseCommand<TModel> command)
{
// delete the thing
return default(TModel);
}
}
public class Program
{
private static Container container;
static void Main(string[] args)
{
container = new Container();
// Order does not seem to matter, I've tried both ways.
container.RegisterOpenGeneric(typeof(ICommandHandler<,>),
typeof(DeleteCommandBaseHandler<>));
container.RegisterOpenGeneric(typeof(ICommandHandler<,>),
typeof(CreateCommandBaseHandler<>));
container.Verify();
// So I want to make the usual hello world
var commandToProcess = new CreateBaseCommand<string> { ItemToCreate = "hello world"};
// Send it away!
Send(commandToProcess);
}
private static void Send<TResult>(ICommand<TResult> commandToProcess)
{
//{CreateBaseCommand`1[[System.String,..."}
var command = commandToProcess.GetType();
//{Name = "String" FullName = "System.String"}
var resultType = typeof (TResult);
//"ICommandHandler`2[[CreateBaseCommand`1[[System.String,..."}
// so it's the right type here
var type = typeof(ICommandHandler<,>).MakeGenericType(command, resultType);
// This is where we break!
var instance = container.GetInstance(type);
// The supplied type DeleteCommandBaseHandler<String> does not implement
// ICommandHandler<CreateBaseCommand<String>, String>.
// Parameter name: implementationType
}
}
을 (Simple Injector 필요) :
그래서 여기 보여줍니다 콘솔 응용 프로그램의 몸입니다. 다시 말해서 순서는 중요하지 않습니다. 나는 잘 작동하는 ICommandHandler<,>
을 상속받은 폐쇄 형 명령 핸들러 (및 해당 명령)가 있습니다.
나는 가능한 모든 유형의 등록을 수행하는 데 많은 시간을 할애하여 this에서 할 수있었습니다.
발생한 버그는 실제로 귀찮습니다. 내 응용 프로그램 중 하나에 데코레이터를 작성할 때 동일한 문제가 발생했습니다. 몇 가지 시나리오에서이 버그를 해결하기가 정말 어렵 기 때문에 다음 번 미성년자 (2.4)를 기다리는 대신이 버그를 수정하기 위해 패치 릴리스 (2.3.6)를 배포 할 것을 고려하고 있습니다. – Steven
그건 좋은 소식인데, 나는 다른 사건을 직접 바라지 않았다. –