2017-05-30 5 views
1

に基づいてオブジェクトを作成し、私は次のコードを持っている:私は、何とかこのスイッチを削除作成し、具体的な型にオブジェクトをキャストしたいは動的タイプ

public async Task DispatchAsync(NoticeChannelType type, string message) 
    { 
     switch (type) 
     { 
      case NoticeChannelType.Email: 
       { 
        var email = JsonConvert.DeserializeObject<NoticeEmail>(message); 
        await _channelResolver.ResolveAsync(email); 
       } 
       break; 
      case NoticeChannelType.Pushover: 
       { 
        var pushover = JsonConvert.DeserializeObject<NoticePushover>(message); 
        await _channelResolver.ResolveAsync(pushover); 
       } 
       break; 
      default: 
       break; 
     } 
    } 

を。

public async Task ResolveAsync<T>(T channel) where T : INoticeChannel 
    { 
     if (channel == null) 
      throw new ArgumentNullException(nameof(channel), 
       $"Channel: '{typeof(T).Name}' cannot be null."); 

     var handler = _context.Resolve<INoticeExecutor<T>>(); 

     await handler.SendAsync(channel); 
    } 

が、私はこのような何かにそれをリファクタリングしようとしていた:

public async Task DispatchAsync(NoticeChannelType type, string message) 
    { 
     var channel = _context.ResolveKeyed<INoticeChannel>(type); 

     Type myType = Type.GetType(channel.GetType().FullName); 

     await _channelResolver.ResolveAsync((INoticeChannel)JsonConvert.DeserializeObject(message, myType)); 
    } 

が、channelResolver.ResolveAsyncタイプで、その後TINoticeChannelとではありません、次のようにそのchannelResolver.ResolveAsync

が実装されていますコンクリートタイプなので_context.Resolve<INoticeExecutor<T>>();は解決できません。

このスイッチを削除してこのコードをよりエレガントに保守しやすくすることはできますか?私はそれがコードをよりエレガント(前者は任意の反射コードのような醜いです)と保守が容易になるだろうか分からないが、

答えて

1

あなたが失う両方の技術で(反射あるいはDLR Dynamic Dispatchのいずれかを使用してResolveAsyncジェネリックメソッドを呼び出すことができますコンパイル時の型の安全性)。

しかし、ここであなたが行く:

リフレクション:

public async Task DispatchAsync(NoticeChannelType type, string message) 
{ 
    var channelType = _context.ResolveKeyed<INoticeChannel>(type).GetType(); 
    var channel = JsonConvert.DeserializeObject(message, channelType); 
    var resolveMethod = _channelResolver.GetType().GetMethod("ResolveAsync") 
     .MakeGenericMethod(channelType); 
    await (Task)resolveMethod.Invoke(_channelResolver, new object[] { channel }); 
} 

ResolveAsyncは、インターフェイスメソッドであればIChannelResolverがあなたのインターフェイス名です、typeof(IChannelResolver)_channelResolver.GetType()を置き換える)

DLR動的ディスパッチを:

public async Task DispatchAsync(NoticeChannelType type, string message) 
{ 
    var channelType = _context.ResolveKeyed<INoticeChannel>(type).GetType(); 
    var channel = JsonConvert.DeserializeObject(message, channelType); 
    await (Task)_channelResolver.ResolveAsync((dynamic)channel); 
} 
+0

大変ありがとうございます。私は、(エレガントで、維持しやすいなど)すべてを持つことができないことを知っていますが、このシナリオでは対処できることを願っています。 –

関連する問題