📄 agenthost.cs
字号:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
//All remoting-related classes are in this namespace and below.
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Threading;
namespace MobileAgents
{
/// <summary>
/// The external interface of the agent host system.
/// It is via this interface that agents are loaded and hosted.
/// </summary>
public class AgentHost : System.MarshalByRefObject
{
#region Private, Static Fields...
/// <summary>
/// Segregates applications into separate domains for extra robustness.
/// </summary>
private static Dictionary<string, AppDomain> _applicationDomains = new Dictionary<string, AppDomain>();
/// <summary>
/// The url of this host.
/// </summary>
private static string _hostUrl = string.Empty;
/// <summary>
/// Make sure to load unknown assemblies into another app domain!
/// A more robust solution would periodically unload this domain and recreate it.
/// </summary>
private static AppDomain _assemblyTesterDomain = new AgentHost().CreateNewAgentDomain("TestLoadDomain");
#endregion
#region Initialization of communication mechanism...
/// <summary>
/// Initializes this host. The logic is internal and can use whatever
/// protocol it wants. However, this implementation uses remoting
/// over a TCP channel.
/// </summary>
/// <param name="port">The port for the TCP Channel to bind to.</param>
/// <param name="objectUri">The uri for this object.</param>
public static void Initialize(int port, string objectUri)
{
//Create a new TcpChannel on the given port and register it with the runtime
TcpServerChannel c = new TcpServerChannel("MyAgentHostChannel", port);
ChannelServices.RegisterChannel(c);
//Register the agent host type with the remoting runtime
RemotingConfiguration.RegisterWellKnownServiceType
(
typeof(AgentHost),
objectUri,
WellKnownObjectMode.SingleCall
);
//Set our url.
_hostUrl = string.Format("tcp://{0}:{1}/{2}", Environment.MachineName, port, "MyAgentHostChannel");
}
#endregion
#region Public Methods...
/// <summary>
/// Checks that the specified assembly is installed (present) on this system.
/// </summary>
/// <param name="assemblyFullName">The full name of the assembly</param>
/// <returns>True/False. True if this assembly is already installed.</returns>
public bool IsAssemblyInstalled(string assemblyFullName)
{
//Test for this agent in ANOTHER app domain.
AgentAssemblyTester adp =
(AgentAssemblyTester)_assemblyTesterDomain.CreateInstanceAndUnwrap(
typeof(AgentAssemblyTester).Assembly.FullName,
typeof(AgentAssemblyTester).FullName);
return adp.IsAssemblyInstalled(assemblyFullName);
}
/// <summary>
/// Uploads an agent assembly or dependent assembly to the host.
/// </summary>
/// <param name="assemblyFullName">The full name of the assembly.</param>
/// <param name="assemblyBits">The assembly file's bits.</param>
public void UploadAssembly(string assemblyFullName, byte[] assemblyBits)
{
AssemblyResolver.SaveAssemblyBits(assemblyFullName, assemblyBits);
}
/// <summary>
/// Hosts the given agent in the default agent application domain.
/// </summary>
/// <param name="agent">The agent to host.</param>
public void HostAgent(Agent agent)
{
//Default to the "" application.
//Don't let them be hosted in the default domain!
HostAgent(string.Empty, agent);
}
/// <summary>
/// Hosts tthe given agent in the specified agent application domain. If
/// the application domain does not exist, it will be created.
/// </summary>
/// <param name="applicationName">The name of the agent application. This parameter is case-sensitive.</param>
/// <param name="agent">The agent to host.</param>
public void HostAgent(string applicationName, Agent agent)
{
try
{
//Get or create an application domain for this application.
AppDomain ad = null;
lock (_applicationDomains)
{
ad =
_applicationDomains.ContainsKey(applicationName) ?
_applicationDomains[applicationName] :
CreateNewAgentDomain(applicationName);
}
//Obtain the class that poses as the interface into that domain
AgentDomainProxy adp =
(AgentDomainProxy)ad.CreateInstanceAndUnwrap(
typeof(AgentDomainProxy).Assembly.FullName,
typeof(AgentDomainProxy).FullName);
//Run the agent in that application domain
adp.HostAgent(agent);
}
catch (Exception ex)
{
//Log an error.
Console.WriteLine(ex.ToString());
throw;
}
}
#endregion
/// <summary>
/// Creates and initializes a new agent application domain.
/// </summary>
/// <param name="applicationName">The name of the application domain to create.</param>
/// <returns>The AppDomain to use for this application.</returns>
private AppDomain CreateNewAgentDomain(string applicationName)
{
//A more secure implementation would augment the call to CreateDomain
//to include the proper security constructs.
AppDomain ad = AppDomain.CreateDomain(applicationName);
//Get an AgentDomainController in the newly created AppDomain
AgentDomainInitializer adi =
(AgentDomainInitializer)ad.CreateInstanceAndUnwrap(
typeof(AgentDomainInitializer).Assembly.FullName,
typeof(AgentDomainInitializer).FullName);
//Create the context for the new appdomain.
HostContext hc = new HostContext(_hostUrl);
//Initialize the new app domain and add to our store!
adi.Initialize(hc);
_applicationDomains.Add(applicationName, ad);
return ad;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -