工作流程:使用服务定位器模式创建依赖关系链

时间:2014-10-01 16:29:04

标签: entity-framework dependency-injection repository-pattern service-locator workflowservice

我试图在我的Workflow应用程序中正确设置依赖项。似乎最好的方法是使用Workflow的WorkflowExtensions提供的服务定位器模式。

我的工作流使用两个存储库:IAssetRepository和ISenderRepository。两者都有使用Entity Framework的实现:EFAssetRepository和EFSenderRepository,但我希望两者都使用相同的DbContext。

我无法同时使用相同的DbContext。我曾经习惯使用IoC进行依赖注入,所以我认为我必须通过构造函数将DbContext注入EF存储库,但这似乎是将服务定位器和IoC模式混合在一起,我无法找到一种简单的方法来实现它,所以我不认为这是前进的方向。

我想我需要链接服务定位器调用?这样我的EF存储库的构造函数就是这样的:

public class EFAssetRepository
{
    private MyEntities entities;

    public EFAssetRepository()
    {
        this.entities = ActivityContext.GetExtension<MyEntities>();
    }
}

显然上面的工作没有成功,因为对ActivityContext的引用已经完成了。

如何使用为WF提供的服务定位器模式实现某种形式的依赖链?

谢谢, 尼克


修改

我已经在下面针对我的问题发布了一个解决方法,但我仍然不满意。我希望代码活动能够调用metadata.Require&lt;&gt;(),因为它应该不知道如何加载扩展,它应该只是期望它们是。实际上,我的metadata.Require&lt;&gt;调用将停止工作流,因为扩展名未加载。

1 个答案:

答案 0 :(得分:0)

似乎有一种方法是在扩展类上实现IWorkflowInstanceExtension,将其转换为一种复合扩展。使用这种方法,我可以解决我的问题:

public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
    private MyEntities entities = new MyEntities();

    IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
    {
        return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
    }

    void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }

    public void SaveChanges()
    {
        this.entities.SaveChanges();
    }
}

这样做的最大缺点是,您无法在CodeActivity的metadata.RequireExtension<IAssetRepository>()方法中调用metadata.RequireExtension<ISenderRepository>()CacheMetadata,这是常见做法。相反,您必须致电metadata.RequireExtension<IUnitOfWork>(),但仍然可以在CodeActivity的context.GetExtension<IAssetRepository>()方法中执行Execute()。我想这是因为在创建任何工作流实例之前调用CacheMetadata方法,如果没有创建工作流实例,则不会调用扩展工厂,因此不会加载其他扩展在WorkflowInstanceExtensionManager中,基本上,在创建工作流实例之前,它不会知道其他扩展。