将内部类注入Azure WebJob函数

时间:2016-06-23 16:10:09

标签: c# azure unity-container azure-webjobs

WebJob项目中的默认Functions类是否有任何方法可以internal?我们正在使用作业激活器通过Unity注入一些internal的依赖项,这要求Functions类也是internal。运行Web作业时,我们看到以下错误:

No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).

当我们创建所有依赖项public时,它运行正常,所以我知道我的触发器或我的作业主机配置没有任何问题。

这是我的课程课程:

class Program
{
    static void Main()
    {
        var config = new JobHostConfiguration
        {
            JobActivator = new Activator(new UnityContainer())
        };
        config.UseServiceBus();
        var host = new JobHost(config);
        host.RunAndBlock();
    }
}

这是我的Functions类的简化版本:

internal class Functions
{
    private readonly IMyInternalDependency _dependency;

    public Functions(IMyInternalDependency dependency)
    {
        _dependency = dependency;
    }

    public function DoSomething([ServiceBusTrigger("my-queue")] BrokeredMessage message)
    {
        // Do something with the message
    }
}

2 个答案:

答案 0 :(得分:1)

您必须公开Functions课程。这似乎就是Azure WebJobs的工作原理。您不需要公开公开具体的内部类。只是界面:

public interface IDoStuffPublically
{
    void DoSomething();
}

interface IDoStuffInternally
{
    void DoSomething();
    void DoSomethingInternally();
}

class DoStuff : IDoStuffPublically, IDoStuffInternally
{
    public void DoSomething()
    {
        // ...
    }

    public void DoSomethingInternally()
    {
        // ...
    }
}

然后是你的Functions课程:

public class Functions
{
    public Functions(IDoStuffPublically stuff)
    {
        _stuff = stuff;
    }

    private IDoStuffPublically _stuff;

    // ...
}

Unity会做这样的事情:

var job = new Functions(new DoStuff());

戴夫评论道:

  

令人沮丧的是,我不能简单地将内部可见设置为WebJob SDK ...

可能能够完成此任务...... miiiiiiiiiight 能够......

程序集或可执行文件有一种方法可以授予另一个程序集访问内部成员的权限。我之前在类库上做过这个,以允许我的单元测试在类上调用内部方法,作为设置单元测试的一部分。

如果您知道Azure WebJobs中的哪个程序集实际创建了Function类的实例,以及调用该类上的方法的程序集,则可以列出这些程序集的白名单。

破解 AssemblyInfo.cs 并添加一行或多行:

[assembly: InternalsVisibleTo("Microsoft.Azure.Something.Something")]

参考:InternalsVisibleToAttribute class

相关阅读:.Net Tips – using InternalsVisibleTo attribute to help testing non-public methods

我不确定您需要添加哪些程序集。

答案 1 :(得分:1)

将Triggers与Webjob SDK一起使用时,您永远不会注册要执行的函数。

当jobhost启动时( var config = new JobHostConfiguration { JobActivator = new Activator(new UnityContainer()) }; config.UseServiceBus(); ),它会根据参数属性发现要执行的函数。

让我们来看看您的代码:

ServiceBusTrigger

因为您指定要使用servicebus,所以当jobhost启动时,它将发现并注册(索引)具有{{1}}属性的参数的所有函数。

我假设SDK使用类似MemberInfo.GetCustomAttributes的内容来索引函数,因此不知道(可能)是否容易从内部类中获取属性。