0

別のアプリケーション ドメインでファクトリ メソッドによって MyClass のインスタンスを作成しようとしていますが、この問題の解決策はありますか? 編集済み:問題はそれを行う方法です

ありがとうございました。

4

1 に答える 1

2

この問題を解決するには、いくつかのオプションがあります。ソリューションをどのように拡張したいか、およびそれがすでにどれだけ複雑であるかに応じて、MAF (System.AddIn 名前空間を参照) を調べてください。また、AppDomains で作成されたオブジェクトの有効期間管理、およびアドインのロード/アンロードとバージョン管理を行うための機能の負荷全体を実装します。

独自の実装を希望する場合、または単に AppDomains の理解を深めたい場合は、次の例が役立つことを願っています。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=[あなたの実行ファイル名]
    人物: Name=Jane Smith、AppDomain=NewDomain
    

    それで、何が起こっているのですか?

    person2 は別の AppDomain のオブジェクトであるため、Serializable にするか、MarshalByRefObject から派生させる必要があります。この例では、MarshalByRefObject から派生させたので、実際のインスタンスは 2 番目の AppDomain にのみ存在し、元の​​ AppDomain の参照は実際にはプロキシです。Serializable 実装を選択した場合、その人物のコピーが元の AppDomain に戻されます。

    これは、新しい AppDomain が呼び出されるたびにパラメーターをマーシャリングする必要があるため、考慮する必要がある別のものであり、パフォーマンスに何らかの影響を与えます。また、MarshalByRefObjects は最終的にタイムアウトになり、ガベージ コレクターによって収集されるため、オブジェクトの有効期間も考慮する必要があります。これをさらに拡張するには、ライフタイム管理を調査する必要があります。

    于 2011-06-09T12:30:28.783 に答える