我在开发使用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应用程序以不同的方式?
我没有得到任何配置错误,但我看到的依赖性还没有被注入,因为到我已经试过注射,属性对象保持为空。
根据我的经验,你不能注入任何东西到你的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基础设施,有一些错误代码,并会触发作用回收。
希望这可以帮助。
我知道这是一个老问题,但我会通过同样的学习曲线,想和大家分享我的发现人谁的斗争,以了解机械。
你不能在你的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和其他服务从划伤。
希望这可以帮助别人更好地理解基础知识。