Dependency injection 使用IoC编写工作流
我正在构建一个WPF应用程序,它使用IoC容器进行依赖注入(在我的例子中是MEF)。该应用程序包含几个详细的流程,我们将这些流程建模为WF工作流。但是,一些(不是全部)活动依赖于由IoC容器管理的服务和其他组件。我看到了一些可能的方法来实现这一点,但它们似乎都没有遵循最佳实践。它们是:Dependency injection 使用IoC编写工作流,dependency-injection,workflow,inversion-of-control,mef,workflow-foundation,Dependency Injection,Workflow,Inversion Of Control,Mef,Workflow Foundation,我正在构建一个WPF应用程序,它使用IoC容器进行依赖注入(在我的例子中是MEF)。该应用程序包含几个详细的流程,我们将这些流程建模为WF工作流。但是,一些(不是全部)活动依赖于由IoC容器管理的服务和其他组件。我看到了一些可能的方法来实现这一点,但它们似乎都没有遵循最佳实践。它们是: 在每个活动的构造函数或执行方法中使用服务定位器来定位 并设置依赖项。就个人而言,我不喜欢服务定位器,因为我认为它们违反了DI的一个租户,而代码不知道依赖关系是在哪里或如何创建的。它还降低了活动的可测试性(或者至少
谢谢 方法二似乎最合适。您可以在xaml中使用一些活动声明,稍后将使用这些声明导入真实的活动声明 编辑:
然后你可以在这些台词中找到一些东西
接口IActivityInfo
{
IActivity ImportActivity();
}
接口IActivityInfo:IActivityInfo
{
IActivityInfo信息{get;}
}
类传递:IActivityInfo
{
public IActivity ImportActivity(){return ServiceLocator.Current.GetInstance();}
}
[导出(类型(活动))]
类传递活动:IActivity
{
}
这种方法可以让您轻松地将xaml设计过程与底层活动分开。方法二似乎最合适。您可以在xaml中使用一些活动声明,稍后将使用这些声明导入真实的活动声明 编辑:
然后你可以在这些台词中找到一些东西
接口IActivityInfo
{
IActivity ImportActivity();
}
接口IActivityInfo:IActivityInfo
{
IActivityInfo信息{get;}
}
类传递:IActivityInfo
{
public IActivity ImportActivity(){return ServiceLocator.Current.GetInstance();}
}
[导出(类型(活动))]
类传递活动:IActivity
{
}
这种方法可以让您轻松地将xaml设计过程与底层活动分开。请详细说明第二句话。因此,最终您将返回到使用服务定位器模式来解决活动。在您的例子中,如果我理解的话,您刚刚创建了一个包装器,可以插入XAML来抽象定位器。您没有显示的是,PassThrough和PassThroughActivity都必须子类化活动(或另一个活动子类型),并且PassThrough必须实现所有方法并委托给“导入的”PassThroughActivity。这需要维护大量代码,特别是当解决方案中有几十个自定义活动需要此行为时。ActivityInfo只需要保存正确初始化活动实例所需的信息。在本例中,我没有使用定位器xaml抽象。。。ActivityInfo不是一个活动,(它是一种生成器模式)。它只需要保存足够的信息就可以正确初始化活动实例。ServiceLocator用于在方法调用期间解析依赖关系(此时不是真正的依赖关系…),而不是在xaml中的ActivityInfo初始化期间解析依赖关系(这可能发生得更早)。所以在xaml中,我得到了ActivityInfo。当需要从中生成真正的工作流时,我称之为导入。是 啊我在工作中遇到过这样的麻烦。我很好奇你是否真的实现了这一点,或者这只是理论上的?我仍然看不到直通是如何不是活动的子类。为了使代码作为工作流的一部分运行,它必须符合工作流运行时(活动)所期望的约定。例如,谁调用ImportActivity,何时调用它?WF希望在活动运行时调用Execute(…),如果PassThrough不是活动的子类,那么模型中的Execute在哪里?请详细说明您的第二句话。因此,最终您将返回到使用服务定位器模式来解析活动。在您的例子中,如果我理解的话,您刚刚创建了一个包装器,可以插入XAML来抽象定位器。您没有显示的是,PassThrough和PassThroughActivity都必须子类化活动(或另一个活动子类型),并且PassThrough必须实现所有方法并委托给“导入的”PassThroughActivity。这需要维护很多代码,特别是当有
<wf:Workflow.Activities></activities:PassThrough UserId="mstewart"></wf:Workflow.Activities>
interface IActivityInfo
{
IActivity ImportActivity();
}
interface IActivity<TActivityInfo> where TActivityInfo : IActivityInfo
{
IActivityInfo Info { get; }
}
class PassThrough : IActivityInfo
{
public IActivity ImportActivity(){ return ServiceLocator.Current.GetInstance<IActivity<PassThrough>>(); }
}
[Export(typeof(IActivity<PassThrough>))]
class PassThroughActivity : IActivity<PassThrough>
{
}