使用不能注入依赖于天青WorkerRole对象Spring.NET(Cannot inject de

2019-07-29 11:50发布

我在开发使用spring.net 4.0,基于ASP.net的Web应用程序的NHibernate 3.0的Web应用程序适中的经验。 最近,我遇到了,我需要使用spring.net注入其中属于我的服务依赖的情况WorkerRole类。 我创建了app.config文件,因为我通常与对春天的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>

然而,我无法注入任何依赖关系到工人的角色。 有人可以请让我知道我做错了什么? 是否存在一种配置Spring.net DI为Windows Azure应用程序以不同的方式?

我没有得到任何配置错误,但我看到的依赖性还没有被注入,因为到我已经试过注射,属性对象保持为空。

Answer 1:

根据我的经验,你不能注入任何东西到你的WorkerRole类(实现RoleEntryPoint类)。 我做什么,至今与统一 (我还建立了自己的帮手团结帮我注射Azure的设置),是,我有我自己的基础设施上运行,并通过统一建的,但我在代码中创建它的工人角色。

例如,我初始化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界面,我可以有许多实现,因为我想,我instiate他们在我的run()方法。 我要做的更多的是有一个WCF服务,通过DI再次完全配置了统一。 这里是我的IWorker接口:

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

仅此而已。 我没有在我的WorkerRole,只是统一容器中的任何“硬”的依赖。 而我在我的两个工人很复杂的DI,一切都运行得很好。

之所以你不能用你的WorkerRole.cs类直接干预,就在于它是由在Windows Azure基础设施实例化,而不是你自己的基础设施。 你必须接受,并WorkerRole适当的方法中建基础设施。 而且不要忘记,你必须永不放弃/休息/返回/退出的run()方法。 这样做会标志的Windows Azure基础设施,有一些错误代码,并会触发作用回收。

希望这可以帮助。



Answer 2:

我知道这是一个老问题,但我会通过同样的学习曲线,想和大家分享我的发现人谁的斗争,以了解机械。

你不能在你的Worker角色类访问DI的原因是因为这是在一个单独的进程在操作系统上运行,IIS之外。 你想想WebRole类作为Windows服务中运行。

我做了一个小实验与我的MVC的Web站点和WebRole类:

public class WebRole : RoleEntryPoint
{
    public override void Run()
    {
        while (true)
        {
            Thread.Sleep(10000);
            WriteToLogFile("Web Role Run: run, Forest, RUN!");
        }
    }

    private static void WriteToLogFile(string text)
    {
        var file = new System.IO.StreamWriter("D:\\tmp\\webRole.txt", true); // might want to change the filename
        var message = string.Format("{0} | {1}", DateTime.UtcNow, text);

        file.WriteLine(message);
        file.Close();
    }
}

这将写入文件每10秒(左右)一个新的字符串。 现在开始在调试模式下您的Azure的站点,请确保部署到Azure的仿真器和VS调试器的网站已经开始。 检查网站运行和检查WebRole被写入到问题的文件。

现在停止IIS快递(或IIS如果你是在完全成熟的安装运行它)不停止与调试。 在您的网站的所有操作,现在都停了下来。 但是,如果你检查你的临时文件,该进程仍在运行,你仍然可以得到新线,每10秒。 直到你停止调试器。

所以,无论你加载Web的应用程序的内存是IIS的内部,而不是可用的工作角色内。 你需要重新配置你的DI和其他服务从划伤。

希望这可以帮助别人更好地理解基础知识。



文章来源: Cannot inject dependencies to Azure WorkerRole object using Spring.NET