我正在尝试在其他应用程序域中通过工厂方法创建 MyClass 的实例,这个问题有什么解决方案吗?编辑:问题是怎么做
谢谢你。
有几个选项可以解决这个问题。根据您希望解决方案如何扩展以及它已经有多复杂,您可能需要查看 MAF(请参阅 System.AddIn 命名空间),因为它处理加载 AddIn 并已经支持 AppDomain 分离。它还实现了与在 AppDomains 中创建的对象的生命周期管理以及加载/卸载 AddIn 和版本控制有关的全部功能。
如果您更愿意实现自己的,或者只是想更多地了解 AppDomain,那么这里有一个示例,希望对您有所帮助。它对 AppDomain 设置、安全性或生命周期管理没有任何作用,并且为了使代码更紧凑,没有错误处理,但它可以用作指南。
如果您从使用工厂创建 Person 对象的示例开始:
public class Person
{
internal Person(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class PersonFactory
{
public static Person CreatePerson(string name)
{
return new Person(name);
}
}
class Program
{
static void Main(string[] args)
{
Person p = PersonFactory.CreatePerson("John Smith");
}
}
然后,您可以添加到此以在另一个 AppDomain 中创建一个 Person,只需对上面的代码进行一些相当简单的更改。
修改后的代码为:
public class Person : MarshalByRefObject
{
internal Person(string name)
{
Name = name;
}
public string Name { get; private set; }
public string AppDomainName { get { return AppDomain.CurrentDomain.FriendlyName; } }
}
public class PersonFactory
{
public static Person CreatePerson(string name)
{
return new Person(name);
}
public static Person CreatePersonInAppDomain(string name, AppDomain domain)
{
return (Person)domain.CreateInstanceAndUnwrap(
typeof(Person).Assembly.FullName,
typeof(Person).FullName,
false,
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { name },
null,
null
);
}
}
class Program
{
static void Main(string[] args)
{
AppDomain domain = AppDomain.CreateDomain("NewDomain");
Person person1 = PersonFactory.CreatePerson("John Smith");
Person person2 = PersonFactory.CreatePersonInAppDomain("Jane Smith", domain);
Console.WriteLine("Person: Name={0}, Domain={1}", person1.Name, person1.AppDomainName);
Console.WriteLine("Person: Name={0}, Domain={1}", person2.Name, person2.AppDomainName);
}
}
输出应该是:
Person: Name=John Smith, AppDomain=[你的 exe 名称] 人员:姓名=简·史密斯,AppDomain=NewDomain
那么发生了什么?
由于 person2 是另一个 AppDomain 中的对象,因此它要么需要可序列化,要么从 MarshalByRefObject 派生。在此示例中,我从 MarshalByRefObject 派生,因此真实实例仅存在于第二个 AppDomain 中,而原始 AppDomain 中的引用实际上是一个代理。如果我选择了 Serializable 实现,那么该人的副本将被传递回原始 AppDomain。
这是需要考虑的其他问题,因为每次调用新的 AppDomain 时都需要编组任何参数,这将对性能产生一些影响。此外,还需要考虑对象的生命周期,因为 MarshalByRefObjects 最终会超时并被垃圾收集器收集。您将需要研究生命周期管理以进一步扩展它。