0

ICommand を実装する可能性がありますが、汎用インターフェイスを実装する可能性があるコマンド オブジェクトがありますIUpdateAggregateCommand<TAggregate>

public interface IUpdateAggregateCommand<TAggregate> : ICommand where TAggregate : IAggregate
{
    TAggregate Entity { get; set; }
}

私はこのようにテストしています:

    var isIUpdateAggregateCommand = command.GetType().GetInterfaces().Any(x =>
        x.IsGenericType &&
        x.GetGenericTypeDefinition() == typeof(IUpdateAggregateCommand<>));

インターフェイスを実装する場合、特定のタイプにキャストするにはどうすればよいですか。たとえば、実装する場合、IUpdateAggregateCommand<Person>コマンドをにキャストするにはどうすればよいIUpdateAggregateCommand<Person>ですか?

Entity の値を設定できるようにする必要があります

アップデート

私はデコレータの中にいて、それをキャストする必要がある集約のタイプがわかりません。したがって、それがどのタイプであるかを把握し、それにキャストする必要があります

4

4 に答える 4

3

直接変換できませんか?

IUpdateAggregateCommand<MyAggregate> updateAggregateCommand = command as IUpdateAggregateCommand<MyAggregate>;
if (updateAggregateCommand != null)
{
    updateAggregateCommand.Entity = ...
}

MyAggregate は、あなたが定義したタイプです (明らかに)。

編集:

実装されたインターフェースをスキャンして単純にキャストすることはできないと思います。リフレクションは、この種の仕事に最適なソリューションかもしれません。実装されたインターフェイスをスキャンし、動的メソッド呼び出しを行ってエンティティを設定できます。次に、エンティティのタイプを把握し、それに応じてインスタンス化または設定する必要があります。タイプセーフとは言えません。

何を達成しようとしていますか?デコレータはどのように実装されていますか? このアプローチが面倒な場合は、問題を解決するための他の解決策があるかもしれません。

于 2013-09-20T16:40:50.433 に答える
2

コマンド変数がそのタイプであるかどうかを確認していただけますか? このコマンド オブジェクトがインスタンス化されたときに継承された場合、true が返されます。

if(command is IUpdateAggregateCommand<TAggregate>)

次に、次のようにします。

var newCommand = ((IUpdateAggregateCommand<TAggregate>)command);

また

var newCommand = command as IUpdateAggregateCommand<TAggregate>;

何にキャストするかわからない更新では、遅いリフレクションを引き続き使用するか、If, Else If高速で読みやすいチェックを行うことができますが、とにかく独自の特別なプロパティ/機能を使用する必要がありますこのタイプに。共通のプロパティを探している場合は、すべてが継承するより一般的なインターフェイスを作成する必要があります。その時点で、とにかく If/Else If は必要ありません。


2 番目の編集: 以下のようなコンセプトをお探しですか? これにより、型に基づいてリストから項目を取得したり、ジェネリック型に基づいて項目を返すことができます。

    List<IMockEvent> events = new List<IMockEvent>();
    public IMockEvent<K> GetMockEvent<T, K>()
    {
        return events.First(t => t is T) as IMockEvent<K>;
    }
    public void Add(IMockEvent evt)
    {
        events.Add(new MockStatusUpdate());
    }

クラスは次のように定義されます

public class EMockStatusUpdated : StatusUpdated, IMockEvent<string> { }
public interface IMockEvent<T> : IMockEvent { }
public interface IMockEvent { }
于 2013-09-20T16:41:11.303 に答える
1

リフレクションを使用してこれを行うことができます。

public static class Extensions
{
    private static readonly MethodInfo SetAggregateInternalMethod = typeof(Extensions)
        .GetMethod("SetAggregateInternal", BindingFlags.Static | BindingFlags.NonPublic);

    private static void SetAggregateInternal<TAggregate>(object item, TAggregate value) where TAggregate : IAggregate
    {
        var aggregateCommand = item as IUpdateAggregateCommand<TAggregate>;
        if (aggregateCommand != null)
            aggregateCommand.Entity = value;
    }

    public static void TrySetAggregate(object item, IAggregate value)
    {
        SetAggregateInternalMethod
            .MakeGenericMethod(value.GetType())
            .Invoke(null, new[] { item, value });
    }
}

キャッシュとコンパイルされたExpressionを使用して、パフォーマンスを向上させることもできます。

于 2013-09-20T16:54:23.363 に答える
1
public interface IAggregate { }
public class Person : IAggregate { }

public interface ICommand { }
public class BaseCommand : ICommand { }

public interface IUpdateAggregateCommand<out T> : ICommand where T : IAggregate
{
    T GetEntity();
}

public class UpdateAggregateCommand<T> : IUpdateAggregateCommand<T> where T : IAggregate
{
    private T entity;
    public void SetEntity(T t) { this.entity = t; }

    public T GetEntity() { return this.entity; }
}


class Program
{
    static void Main(string[] args)
    {
        var command = new BaseCommand();
        var obj = command as IUpdateAggregateCommand<IAggregate>;
        if (obj != null)
            Console.WriteLine(obj.GetEntity().GetType());

        var command1 = new UpdateAggregateCommand<Person>();
        command1.SetEntity(new Person());
        var obj1 = command1 as IUpdateAggregateCommand<IAggregate>;
        if (obj1 != null)
            Console.WriteLine(obj1.GetEntity().GetType());
    }
}
于 2013-09-20T18:23:13.573 に答える