📄 agent.cs
字号:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace MobileAgents
{
/// <summary>
/// Abstract class that any agent implementation MUST inherit from.
/// Provides base functionality for agents.
/// </summary>
[Serializable()]
public abstract class Agent
{
/// <summary>
/// Event that fires once this agent has moved to another host.
/// Used only by AgentProxy
/// </summary>
[field:NonSerialized()]
public event System.EventHandler AgentMoved;
/// <summary>
/// Protected Ctor.
/// </summary>
protected Agent() {}
/// <summary>
/// The method called to execute an agent's logic.
/// </summary>
protected internal abstract void Run();
#region Moving Methods...
/// <summary>
/// Moves this agent to the given host.
/// </summary>
/// <param name="urlOfHostToMoveTo">The url of the host to move to.
/// The url format depends on the protocol being used.</param>
public void Move(string urlOfHostToMoveTo)
{
AgentHost h = (AgentHost)Activator.GetObject
(
typeof(AgentHost),
urlOfHostToMoveTo
);
TransferAgentAssembliesToHost(h);
//Now move ourselves!
h.HostAgent(this);
//Signal that we have moved.
if (AgentMoved != null)
AgentMoved(this, null);
}
/// <summary>
/// Ensures that all referenced assemblies are available on the remote host.
/// </summary>
/// <param name="h">The proxy to the remote AgentHost object</param>
private void TransferAgentAssembliesToHost(AgentHost h)
{
//Get the full name of the assembly this agent is defined in.
AssemblyName thisAssemblyName = this.GetType().Assembly.GetName();
//If this hasn't been installed yet, we must walk the assembly
//dependency graph to see what assemblies need to be transferred.
if (!h.IsAssemblyInstalled(thisAssemblyName.FullName))
{
//Recursively Find Assemblies Dependencies based on references
Dictionary<string, AssemblyName> assembliesFound = new Dictionary<string, AssemblyName>();
FindReferencedAssemblies(assembliesFound, this.GetType().Assembly.GetName());
//Now, for each assembly found, attempt to upload.
foreach(AssemblyName an in assembliesFound.Values)
{
if (!h.IsAssemblyInstalled(an.FullName))
h.UploadAssembly(an.FullName, GetRawAssembly(Assembly.Load(an)));
}
}
}
/// <summary>
/// Recursive method that will create a mapping of all referenced assemblies.
/// </summary>
/// <param name="assembliesFound">A dictionary of the assemblies found so far.</param>
/// <param name="assemblyToSearch">The name of the assembly to get references for.</param>
private void FindReferencedAssemblies(Dictionary<string, AssemblyName> assembliesFound, AssemblyName assemblyToSearch)
{
//Check to see that we haven't encountered this assembly yet.
//If we don't --> Stack Overflow
if (!assembliesFound.ContainsKey(assemblyToSearch.FullName))
{
//Add current assembly
assembliesFound.Add(assemblyToSearch.FullName, assemblyToSearch);
//Get all of its references
AssemblyName[] references = Assembly.Load(assemblyToSearch).GetReferencedAssemblies();
foreach (AssemblyName reference in references)
{
FindReferencedAssemblies(assembliesFound, reference);
}
}
}
/// <summary>
/// Reads in an assemblies bits from the disk into a byte array.
/// </summary>
/// <param name="a">The assembly to get the bits of.</param>
/// <returns>A byte[] containing the assembly file's bits.</returns>
private byte[] GetRawAssembly(Assembly a)
{
byte[] buffer = null;
using (FileStream fs = File.OpenRead(a.Location))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
}
return buffer;
}
#endregion
/// <summary>
/// Agent factory method that will create an instance of the agent type specified.
/// </summary>
/// <param name="agentType">The .NET type of the agent to create.</param>
/// <param name="agentConstructorArgs">Any optional arguments to use for the types constructor.</param>
/// <returns>An AgentProxy instance containing the new agent.</returns>
public static AgentProxy CreateAgent(Type agentType, params object[] agentConstructorArgs)
{
//Double-check that we are creating an Agent subclass
if (!agentType.IsSubclassOf(typeof(Agent)))
throw new Exception(string.Format("Type '{0}' is not a subclass of type Agent.", agentType.ToString()));
//Attempt to create it
object o = agentType.InvokeMember(string.Empty, BindingFlags.CreateInstance, null, null, agentConstructorArgs);
Agent agent = o as Agent;
//Make sure we were successful!
if (agent == null)
throw new Exception("Unable to create Agent instance.");
//Wrap the new agent with a proxy and return the proxy.
return new AgentProxy(agent);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -