我想在我的Windows Azure Web应用程序中重用自托管Web应用程序中的一些代码逻辑。目前我的代码如下:
void myFunction( params )
{
//environment-neutral code
}
我需要重写该代码,以使程序采取不同的行动,具体取决于是否在Azure上:
void myFunctionModified( params )
{
if( onAzure() ) {
//run Azure-specific code
} else {
//run non-Azure code
}
}
是的,我知道虚函数,但我需要这样的代码,至少可以在调用那些虚函数之前实例化正确的对象。
问题是实现onAzure()
我需要使用仅存在于Windows Azure上的程序集中的东西(例如RoleEnvironment
)。所以我看不出如何实现onAzure()
,以便在Windows Azure环境之外运行时不会崩溃。
如何根据系统中存在的程序集使应用程序采取不同的行为?
答案 0 :(得分:8)
你能用:
Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.IsAvailable
来自Determine if app is running in azure or not
如果您不想在库中包含对Microsoft.WindowsAzure.ServiceRuntime的引用,那么您可以尝试使用AppDomain.CurrentDomain.GetAssemblies()
和一些Linq在已加载的程序集中检查它。
bool runtimeAvailable = AppDomain.CurrentDomain.GetAssemblies().Any(
assembly => assembly.FullName.StartsWith("Microsoft.Microsoft.WindowsAzure.ServiceRuntime"));
或者您可以尝试使用Microsoft.WindowsAzure.ServiceRuntime
加载Assembly.Load
程序集并检查FileNotFoundException
作为对虚函数的评论的替代/补充,您可以考虑使用依赖注入。
答案 1 :(得分:3)
如果您需要编写有条件地依赖于不同程序集的代码,您可以使用conditional compilation 构建应用程序的不同版本来定位两个托管模型:
public void MyFunction()
{
#if AZURE
// Code that depends on the Azure assemblies
#elseif
// Code that depends on the .NET Framework assemblies
#end if
}
然后,您可以在项目文件中定义一个定义AZURE
编译器符号的特定build configuration,如下例所示:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Azure|AnyCPU' ">
<DefineConstants>TRACE;AZURE</DefineConstants>
</PropertyGroup>
答案 2 :(得分:2)
如果您不能使用条件编译符号,那么其他答案已建议......
您是否可以尝试使用仅存在于Azure上的反射来获取类型? 如果找不到类型,那么你就不在Azure上了。
或者,如果您想沿着程序集路径前进,那么您可以检查AppDomain.CurrentDomain.GetAssemblies()
以获取Azure程序集。
答案 3 :(得分:2)
对于依赖注入来说,这看起来非常好。需要Windows Azure RoleEntryPoint或其他Windows Azure特定功能的功能应该隐藏在注入的接口后面(Autofac,Unity,Castle Windsor,Ninject,MEF等)。在构建DI容器时,只需在部署到Windows Azure而不是内部部署时执行不同的操作(MyOnPremisesImplementation:IMyFunctionProvider,与MyAzureImplementation:IMyFunctionProvider相比)。