0

我正在尝试在其他应用程序域中通过工厂方法创建 MyClass 的实例,这个问题有什么解决方案吗?编辑:问题是怎么做

谢谢你。

4

1 回答 1

2

有几个选项可以解决这个问题。根据您希望解决方案如何扩展以及它已经有多复杂,您可能需要查看 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,只需对上面的代码进行一些相当简单的更改。

  • 使类 Person 成为 MarshalByRefObject
  • 将另一个属性添加到将输出其 AppDomain 以进行测试的 Person
  • 向工厂添加另一个静态方法以在不同的 AppDomain 中创建
  • 修改后的代码为:

    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 最终会超时并被垃圾收集器收集。您将需要研究生命周期管理以进一步扩展它。

    于 2011-06-09T12:30:28.783 回答