使用Unity从Azure WebJob注入另一个项目的依赖项

时间:2016-08-21 02:05:34

标签: c# .net entity-framework unity-container azure-webjobs

我的解决方案中有两个项目 - 一个Web项目和一个控制台应用程序。

网络项目

在我的网络项目中,我有以下工作:

public class TestService : BaseService {
    private BrowseService _browseService;
    public TestService(BrowseService browseService) {
        _browseService = browseService;
    }

    public ApiResponseDto DoStuff(string username) {

        using (var db = new AppContext()) {
            var user = db.FindUser(username);
            // do stuff with _browseService here
        }
    }
 }

我在这里使用Unity for DI。

控制台应用

现在,我从我的控制台应用程序中引用我的Web项目并执行以下操作:

public class Functions {
    private TestService _testService;
    public Functions(TestService testService) {
        _testService = testService;
    }

    public static void ProcessStuff([QueueTrigger("my-queue")] string userId) {
        using (var db = new AppContext()) { // works
            _testService.DoStuff(userId) // _testService isn't available
        }
    }

问题

如何在我的控制台应用中使用DI?我添加了Unity,然后我这样做了:

    static void Main() {
        var container = new UnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        var host = new JobHost();
        // The following code ensures that the WebJob will be running continuously
        host.RunAndBlock();
    }

但是,上面的构造函数永远不会被命中,_testService永远不可用。

更新

我尝试了以下内容:

static void Main() {
    var container = new UnityContainer();
    var host = container.Resolve<JobHost>().
    host.RunAndBlock();
}

但是我得到一个例外:

  

Microsoft.Practices.Unity.ResolutionFailedException未处理
  _HResult = -2146233088 _message =依赖项的解析失败,type =“Microsoft.Azure.WebJobs.JobHost”,name =“(none)”。例外   发生在:同时解决。例外情况是:   InvalidOperationException - 无法构造String类型。您   必须配置容器以提供此值。    - - - - - - - - - - - - - - - - - - - - - - - - 当时例外,容器是:

     

解决Microsoft.Azure.WebJobs.JobHost,(无)解析   参数“配置”的构造函数   Microsoft.Azure.WebJobs.JobHost(Microsoft.Azure.WebJobs.JobHostConfiguration   组态)       解决Microsoft.Azure.WebJobs.JobHostConfiguration,(无)       解析构造函数Microsoft.Azure.WebJobs.JobHostConfiguration(System.String)的参数“dashboardAndStorageConnectionString”   dashboardAndStorageConnectionString)         解析System.String,(无)

     

HResult = -2146233088 IsTransient = false消息=分辨率   依赖失败,type =“Microsoft.Azure.WebJobs.JobHost”,name =   “(没有)”。在解决时发生异常:例外情况是:   InvalidOperationException - 无法构造String类型。您   必须配置容器以提供此值。

更新2

我现在根据这个问题Dependency injection using Azure WebJobs SDK?得到以下内容:

class Program {
    static void Main() {
        var container = new UnityContainer();
        var config = new JobHostConfiguration {
            JobActivator = new MyActivator(container)
        };
        var host = new JobHost(config);
        // The following code ensures that the WebJob will be running continuously
        host.RunAndBlock();
    }
}

public class MyActivator : IJobActivator {
    private readonly IUnityContainer _container;

    public MyActivator(IUnityContainer container) {
        _container = container;
    }

    public T CreateInstance<T>() {
        return _container.Resolve<T>();
    }
}

但是,_testService仍为null,Functions的注入构造函数永远不会执行。

2 个答案:

答案 0 :(得分:1)

根据您的代码,我已经在我身边进行了测试并将其解决了。请尝试按照以下代码检查它是否可以帮助您:

网络项目

public class TestService : BaseService
{
    private BrowseService _browseService;
    public TestService(BrowseService browseService)
    {
        _browseService = browseService;
    }

    public string DoStuff(string username)
    {
        return _browseService.DoStuff(username);
    }
}

public class BaseService { }

public abstract class BrowseService
{
    public abstract string DoStuff(string username);
}

public class MyBrowseService : BrowseService
{
    public override string DoStuff(string username)
    {
        return string.Format("MyBrowseService.DoStuff is invoked with value={0}", username);
    }
}

控制台应用

1)Functions.cs

public class Functions
{
    private static TestService _testService;
    public Functions(TestService testService)
    {
        _testService = testService;
    }

    public void ProcessStuff([QueueTrigger("my-queue")] string userId)
    {
        try
        {
            Console.WriteLine("ProcessStuff is invoked with value={0}", userId);
            string result = _testService.DoStuff(userId);
            Console.WriteLine("ProcessStuff return the result:\r\n{0}", result);
        }
        catch (Exception e)
        {
            Console.WriteLine("ProcessStuff executed with errors.\r\n{0}\r\n{1}", e.Message, e.StackTrace);
        }
    }
}

注意:您应该将WebJob函数设置为实例函数而不是静态函数。

2)的Program.cs

static void Main()
{
    UnityContainer container = new UnityContainer();
    container.RegisterType<BrowseService, MyBrowseService>();
    container.RegisterType<Functions>(); //Need to register WebJob class
    var config = new JobHostConfiguration()
    {
        JobActivator = new UnityJobActivator(container)
    };
    var host = new JobHost(config);
    host.RunAndBlock();
}

结果: enter image description here

答案 1 :(得分:0)

DependencyResolver是一个MVC构造;它不用于控制台应用程序。要使其工作,请将主方法更改为:

static void Main() {
        var container = new UnityContainer();
        var host = container.Resolve<JobHost>().
        host.RunAndBlock();
    }

然后,只要你使用构造函数注入,一切都应该按预期工作。