开发者

How can my C# program behave differently depending on what assemblies are present?

I want to reuse some code logic from a self-hosted web application in my Windows Azure web application. Currently I have code like this:

void myFunction( params )
{
   //environment-neutral code
}

I need to rewrite that code to make the program act differently depending on whet开发者_StackOverflowher is is on Azure:

void myFunctionModified( params )
{
    if( onAzure() ) {
       //run Azure-specific code
    } else {
       //run non-Azure code
    }
}

yes, I know about virtual functions, but I'll need such code for at least instantiating the right object before I can call those virtual functions.

The problem is to implement onAzure() I need to use stuff from an assembly that is only present on Windows Azure (like RoleEnvironment for example). So I don't see how I can implement onAzure() so that it doesn't crash when run outside Windows Azure environment.

How do I make my application act differently depending on what assemblies are present on the system?


Can you use:

Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.IsAvailable

from Determine if app is running in azure or not


If you don't want to include a reference to Microsoft.WindowsAzure.ServiceRuntime in your library, then you could try checking for it in the loaded assemblies using AppDomain.CurrentDomain.GetAssemblies() and some Linq - e.g.

bool runtimeAvailable = AppDomain.CurrentDomain.GetAssemblies().Any(
    assembly => assembly.FullName.StartsWith("Microsoft.Microsoft.WindowsAzure.ServiceRuntime"));

Or you could try loading the Microsoft.WindowsAzure.ServiceRuntime assembly using Assembly.Load and checking for a FileNotFoundException


As an alternative/addition to your comment about virtual functions, you could consider using dependency injection.


If you need to write code that conditionally depends on different assemblies, you could use conditional compilation to build different versions of your app to target the two hosting models:

    public void MyFunction()
    {
#if AZURE
        // Code that depends on the Azure assemblies
#elseif
        // Code that depends on the .NET Framework assemblies
#end if
    }

You could then define a specific build configuration in your project file that defines the AZURE compiler symbol, like in this example:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Azure|AnyCPU' ">
    <DefineConstants>TRACE;AZURE</DefineConstants>
</PropertyGroup>


If you can't use conditional compilation symbols as other answers have suggested then...

Could you try and get a type using reflection that only exists on Azure? If it can't find the type then you're not on Azure.

Or, if you want to go down the assemblies route, then you could check AppDomain.CurrentDomain.GetAssemblies() for your Azure assembly.


This really looks like a good case for dependency injection. The functionality that requires Windows Azure RoleEntryPoint or other Windows Azure specific functionality should be tucked behind an interface that is injected (Autofac, Unity, Castle Windsor, Ninject, MEF, etc.). When you build your DI container, you would simply do it differently when deploying to Windows Azure versus on-premises (MyOnPremisesImplementation : IMyFunctionProvider, vs. MyAzureImplementation : IMyFunctionProvider).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜