【问题标题】:Process list of object by type按类型处理对象列表
【发布时间】:2015-04-27 13:35:31
【问题描述】:

我需要创建一个 Sync 方法。 1) 在输入时,它需要 SyncRequest 对象。

class SyncRequest{
    public List<SyncObj> Objects{get;set;}
}
class SyncObj{
    public Type Type{get;set;}
    public object Object{get;set;}
}

2) 根据每个对象的类型,我需要使用不同的服务进行处理,并使用不同的存储库来保存数据。

即如果我得到了用户、用户、任务类型的 3 个对象。我将按类型对它们进行分组,然后继续使用 UserService 和 TaskService。
我正在尝试使用 Onion Architecture 构建我的 web.api。 DataAccess、Core、Services 是相互分离的。我想在我的代码中避免使用 swich 或 if's。

我提出的所有想法都很丑陋。例如Dicitionary&lt;Type, Service&gt;,以及手动转换。

我觉得 Ninject 可能对我的问题有很好的回答,有一些工厂功能,但我想不出。

谁能描述这种模式应该如何工作。或者这种模式如何调用,在哪里阅读。

【问题讨论】:

  • 不确定我是否理解正确,但Handler-Patern 似乎很合适。
  • 不同服务(UserServiceTaskService)是否共享一个接口?
  • This article 描述了@john 更详细描述的处理程序模式。

标签: c# ninject asp.net-web-api nancy onion-architecture


【解决方案1】:

由于您所拥有的只是Type,因此您将不得不使用反射。另一个问题是您如何访问 DI 容器(ninject 内核)。

你可以这样做:

public interface IHandler<T>
{
    void Handle(T obj);
}

public void UserService : IHandler<User> {...}

Bind<IHandler<User>>().To<UserService>();

然后你会像这样使用它:

foreach(var syncObj in syncRequest.Objects) 
{
    Type handlerType = typeof(IHandler<>).MakeGeneric(syncObj.Type);
    MethodInfo handleMethod = handlerType.GetMethod("Handle");

    object handler = kernel.Get(handlerType);

    handleMethod.Invoke(handler, new object[] { syncObj.Object });
}

如您所见,您需要以某种方式访问容器来创建特定类型。您可以将其注入为IResolutionRoot。 要遵守洋葱分层,您必须将使用内核的代码移动到组合根并为其提供接口...... 既然你似乎知道洋葱分层,我就不再赘述了:)

【讨论】:

  • 对象处理程序 = kernel.Get(handler);你是说 .Get(handlerType) 吗?
  • 顺便说一句。我只是将它编码为纯文本,没有编译它,所以可能会有其他小错误。
  • 此解决方案需要具有作为构造函数注入具有内核的工厂。我不记得在哪里,但我读到在代码中的其他地方而不是 Resolver 类中使用内核不是一个好习惯
  • 也许在Mark Seeman's Blog?。为了更好地符合“他的”原则,您必须使工厂成为 Composition 根的一部分。这意味着顶层——它应该是应用程序中唯一可能知道 DI 容器的部分。
猜你喜欢
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
相关资源
最近更新 更多