#region License
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#if (!NET_1_0 && !MONO)
#region Imports
using System;
using System.Configuration;
using System.Diagnostics;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Xml;
using Spring.Context;
using Spring.Context.Support;
using Spring.Core.IO;
using Spring.Objects.Factory.Config;
using Spring.Util;
using ConfigXmlDocumentSpring.Util.ConfigXmlDocument;
#endregion
namespace Spring.EnterpriseServices{
/// <summary>
/// This class supports <see cref="ServicedComponent"/>s exported using <see cref="EnterpriseServicesExporter"/>.
/// and must never be used directly.
/// </summary>
/// <author>Erich Eichinger</author>
public class ServicedComponentHelper
{
private static bool isInitialized;
private static string componentDirectory;
private static IApplicationContext _appContext;
static ServicedComponentHelper()
{
isInitialized = false;
}
///<summary>
/// Reads in the 'xxx.spring-context.xml' configuration file associated with the specified <paramref name="componentType"/>.
/// See <see cref="EnterpriseServicesExporter"/> for an in-depth description on how to export and configure COM+ components.
///</summary>
public static void EnsureComponentContextRegistryInitialized(Type componentType)
{
if (isInitialized) return;
lock (typeof(ServicedComponentHelper))
{
if (isInitialized) return;
isInitialized = true;
// this is to ensure, that assemblies placed next to the component assembly can be loaded
// even when they are not strong named.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
FileInfo componentAssemblyFile = new FileInfo(componentType.Assembly.Location);
componentDirectory = componentAssemblyFile.Directory.FullName;
// switch to component assembly's directory (affects resolving relative paths during context instantiation!)
Environment.CurrentDirectory = componentDirectory;
// read in config file if any
FileInfo configFile = new FileInfo(componentAssemblyFile.FullName);
if (configFile.Exists)
{
bool isRunningOutOfProcess = IsRunningOutOfProcess();
#if NET_2_0
ExeConfigurationSystem comConfig = new ExeConfigurationSystem(configFile.FullName);
if (isRunningOutOfProcess)
{
Trace.WriteLine(string.Format("configuring COM OutProc Server '{0}' using '{1}'", componentAssemblyFile.FullName, componentAssemblyFile.FullName + ".config"));
// make the config "global"
ConfigurationUtils.SetConfigurationSystem(comConfig, true);
_appContext = ContextRegistry.GetContext();
if (_appContext == null)
{
throw ConfigurationUtils.CreateConfigurationException("Spring-exported COM components require <spring/context> section");
}
}
else
{
Trace.WriteLine(string.Format("configuring COM InProc Server '{0}' using section <spring/context> from file '{1}'", componentAssemblyFile.FullName, componentAssemblyFile.FullName + ".config"));
_appContext = (IApplicationContext)comConfig.GetSection("spring/context");
if (_appContext == null)
{
throw ConfigurationUtils.CreateConfigurationException("Spring-exported COM components require <spring/context> section in configuration file");
}
}
#else
_appContext = (IApplicationContext) ConfigurationReader.GetSection(new FileSystemResource(configFile.FullName + ".config"),"spring/context");
if (_appContext == null)
{
throw ConfigurationUtils.CreateConfigurationException("Spring-exported COM components require <spring/context> section in configuration file");
}
#endif
}
else
{
Trace.WriteLine(string.Format("No configuration file '{0}' for COM component '{1}' found - bypassing configuration", componentAssemblyFile.FullName + ".config", componentAssemblyFile.FullName));
}
}
}
private static bool IsRunningOutOfProcess()
{
// TODO: checkout a prob. better way to find out, whether we are executing as a com server or library
return AppDomain.CurrentDomain.SetupInformation.ApplicationName == "dllhost.exe";
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string name = args.Name.Split(',')[0];
Assembly assembly = Assembly.LoadFrom(Path.Combine(componentDirectory, name + ".dll"));
return assembly;
}
///<summary>
/// Called by a <see cref="ServicedComponent"/> exported by <see cref="EnterpriseServicesExporter"/>
/// to obtain a reference to the service it proxies.
///</summary>
public static object GetObject(ServicedComponent sender, string targetName)
{
EnsureComponentContextRegistryInitialized(sender.GetType());
if (_appContext == null)
{
throw ConfigurationUtils.CreateConfigurationException("Spring-exported COM components require <spring/context> section in configuration file");
}
return _appContext.GetObject(targetName);
}
}
}
#endif
|