Reputation: 12915
I have two projects in my solution - a web project, and a console app.
Web Project
From within my web project, I have the following working:
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
}
}
}
I'm using Unity for DI here.
Console App
Now, I reference my web project from my console app and do the following:
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
}
}
Problem
How do I get DI working in my console app? I've added Unity and then I do this:
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();
}
However, the constructor above never gets hit and _testService
is never available.
Update
I've attempted the following:
static void Main() {
var container = new UnityContainer();
var host = container.Resolve<JobHost>().
host.RunAndBlock();
}
However I get an exception:
Microsoft.Practices.Unity.ResolutionFailedException was unhandled
_HResult=-2146233088 _message=Resolution of the dependency failed, type = "Microsoft.Azure.WebJobs.JobHost", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value. ----------------------------------------------- At the time of the exception, the container was:Resolving Microsoft.Azure.WebJobs.JobHost,(none) Resolving parameter "configuration" of constructor Microsoft.Azure.WebJobs.JobHost(Microsoft.Azure.WebJobs.JobHostConfiguration configuration) Resolving Microsoft.Azure.WebJobs.JobHostConfiguration,(none) Resolving parameter "dashboardAndStorageConnectionString" of constructor Microsoft.Azure.WebJobs.JobHostConfiguration(System.String dashboardAndStorageConnectionString) Resolving System.String,(none)
HResult=-2146233088 IsTransient=false Message=Resolution of the dependency failed, type = "Microsoft.Azure.WebJobs.JobHost", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.
Update 2
I now have the following per this question 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>();
}
}
However, _testService
is still null and the injection constructor for Functions
is never executed.
Upvotes: 0
Views: 1064
Reputation: 3293
Based on your code, I have tested it on my side and worked it out. Please try to follow the code below to check whether it could help you:
Web Project
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);
}
}
Console App
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);
}
}
}
Note: You should set the WebJob function as an instance function not a static function.
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();
}
Upvotes: 1
Reputation: 7484
DependencyResolver is an MVC construct; it isn't used in a console app. To make this work, change your main method to:
static void Main() {
var container = new UnityContainer();
var host = container.Resolve<JobHost>().
host.RunAndBlock();
}
Then, as long as you use constructor injection, everything should work as expected.
Upvotes: 0