无法使用 Spring.NET 将依赖项注入到 Azure WorkerRole 对象

2024-05-03

我在使用 spring.net 4.0 和 nhibernate 3.0 开发基于 ASP.net 的 Web 应用程序方面拥有一定的经验。最近我遇到了一种情况,我需要使用 spring.net 来注入我的服务依赖项,这些依赖项属于WorkerRole班级。我创建了 app.config 文件,就像我通常为 spring 创建 web.config 文件一样。这是为了清楚起见。 (我已经排除了根节点)

<configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web" requirePermission="false" />
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" requirePermission="false" />
      <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>
    <spring>
    <context>
      <!-- Application services and data access that has been previously developed and tested-->
      <resource uri="assembly://DataAccess/data-access-config.xml" />
      <resource uri="assembly://Services/service-config.xml" />
      <resource uri="AOP.xml" />
      <resource uri="DI.xml"/>
    </context>
    <parsers>
      <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" />
      <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" />
      <parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" />
    </parsers>
  </spring>

同样这是 AOP.xml

<object id="FilterServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
    <property name="proxyInterfaces" value="Domain.IFilterService"/>
    <property name="target" ref="FilterService"/>
    <property name="interceptorNames">
      <list>
        <value>UnhandledExceptionThrowsAdvice</value>
        <value>PerformanceLoggingAroundAdvice</value>
      </list>
    </property>
  </object>
</objects>

和 DI.xml

<object type="FilterMt.WorkerRole, FilterMt" >
  <property name="FilterMtService1" ref="FilterServiceProxy"/>
</object>

但是,我无法将任何依赖项注入到辅助角色中。有人可以让我知道我在这里做错了什么吗?是否有不同的方法为 Windows Azure 应用程序配置 Spring.net DI?

我没有收到任何配置错误,但我看到依赖项尚未注入,因为我尝试注入的属性对象仍然为空。


根据我的经验,您不能将任何内容注入您的 WorkerRole 类(实现 RoleEntryPoint 的类)。到目前为止我所做的Unity http://nuget.org/packages/UASI(我还为 Unity 构建了自己的帮助程序来帮助我注入 Azure 设置),就是我有自己的基础设施,由 Unity 运行和构建,但我在辅助角色的代码中创建它。

例如,我在 RoleEntry 点的 OnStart() 方法中初始化依赖项容器,在其中解决我需要的任何内容。然后在我的 Run() 方法中,我调用已解析的依赖项上的方法。

这是我的 RoleEntryPoint 实现的快速、精简版本:

public class WorkerRole : RoleEntryPoint
{
    private UnityServiceHost _serviceHost;
    private UnityContainer _container;

    public override void Run()
    {
        // This is a sample worker implementation. Replace with your logic.
        Trace.WriteLine("FIB.Worker entry point called", "Information");
        using (this._container = new UnityContainer())
        {
            this._container.LoadConfiguration();
            IWorker someWorker = this._container.Resolve<IWorker>();
            someWorker.Start();

            IWorker otherWorker = this._container.Resolve<IWorker>("otherWorker");
            otherWorker.Start();

            while (true)
            {
                // sleep 30 minutes. we don't really need to do anything here.
                Thread.Sleep(1800000);
                Trace.WriteLine("Working", "Information");
            }
        }
    }

    public override bool OnStart()
    {
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

        this.CreateServiceHost();

        return base.OnStart();
    }

    public override void OnStop()
    {
        this._serviceHost.Close(TimeSpan.FromSeconds(30));    
        base.OnStop();
    }

    private void CreateServiceHost()
    {
        this._serviceHost = new UnityServiceHost(typeof(MyService));

        var binding = new NetTcpBinding(SecurityMode.None);
        RoleInstanceEndpoint externalEndPoint =
            RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ServiceEndpoint"];
        string endpoint = String.Format(
            "net.tcp://{0}/MyService", externalEndPoint.IPEndpoint);
        this._serviceHost.AddServiceEndpoint(typeof(IMyService), binding, endpoint);
        this._serviceHost.Open();
    }

正如您所看到的,我自己的逻辑是 IWorker 接口,我可以拥有任意数量的实现,并且我在 Run() 方法中实例化它们。我所做的更多的是拥有一个 WCF 服务,同样通过 Unity 的 DI 完全配置。这是我的 IWorker 界面:

public interface IWorker : IDisposable
{
    void Start();
    void Stop();
    void DoWork();
}

就是这样。我的 WorkerRole 中没有任何“硬”依赖项,只有 Unity 容器。我的两个工作人员中有非常复杂的 DI,一切都运行良好。

您无法直接干预 WorkerRole.cs 类的原因是,它是由 Windows Azure 基础结构实例化的,而不是由您自己的基础结构实例化的。您必须接受这一点,并在 WorkerRole 适当的方法中构建您的基础设施。并且不要忘记,您绝不能退出/中断/返回/退出 Run() 方法。这样做将标记 Windows Azure 基础设施,表明您的代码存在问题,并将触发角色回收。

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法使用 Spring.NET 将依赖项注入到 Azure WorkerRole 对象 的相关文章

随机推荐