我的解决方案中有两个项目 - 一个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
的注入构造函数永远不会执行。
答案 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();
}
答案 1 :(得分:0)
DependencyResolver是一个MVC构造;它不用于控制台应用程序。要使其工作,请将主方法更改为:
static void Main() {
var container = new UnityContainer();
var host = container.Resolve<JobHost>().
host.RunAndBlock();
}
然后,只要你使用构造函数注入,一切都应该按预期工作。