を横断するとき、私は私の問題の根本的な原因は、これと同様の問題であると確信しているタイプをターゲットに変換することができません。オブジェクトタイプはのAppDomain
How do I pass references as method parameters across AppDomains?
とthis answer特に、私はかなりよく分かりませんそれを修正する方法。
これは私が書いているVisual Studio拡張機能があり、それができるようにするために必要なことの1つはアセンブリを別のドメインにロードすることです私はそれでやった)とそれでいくつかのものをする。だから私は自分のドメインは、次のように設定している:
// The actual ApplicationBase of the current domain will be the one of VS and not of my plugin
// We need our new AppDomain to be able to find our assemblies
var p = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var setup = new AppDomainSetup()
{
ApplicationBase = p
};
domain = AppDomain.CreateDomain("MyTest_AppDomain", AppDomain.CurrentDomain.Evidence, setup);
var t = typeof(Proxy);
proxy = domain.CreateInstanceAndUnwrap(t.Assembly.FullName,
t.FullName,
false,
BindingFlags.Default,
null,
new object[] { assemblyPath },
null,
null) as Proxy;
私はそれは上のコードと同じアセンブリで定義されていていても私のクラスProxy
をロードできるようにするためApplicationBase
を設定する必要がありました。戻る私のようなものを持っている新しいAppDomain
の新しいAppDomain
とProxy
のインスタンスを作成した同じクラスの
public class Proxy : MarshalByRefObject
{
private Assembly _assembly;
private IEnumerable<Type> _types;
public IEnumerable<Type> Types
{
get
{
if (_types == null && _assembly != null)
{
_spiders = _assembly.GetTypes().Where(t => typeof(IFoo).IsAssignableFrom(t)).ToList();
}
return _types;
}
}
public Proxy(string assemblyPath)
{
_assembly = Assembly.LoadFile(assemblyPath);
}
public IFoo GetInstanceOf(string fooType)
{
var type = Types.FirstOrDefault(t => t.FullName == fooType);
if (type == null)
{
throw new InvalidOperationException($"Unknown type {fooType} in assembly {_assembly.FullName}");
}
return GetInstanceOf(type);
}
private IFoo GetInstanceOf(Type fooType)
{
var obj = Activator.CreateInstance(fooType);
return obj as IFoo;
}
public override object InitializeLifetimeService()
{
return null;
}
}
:それがなければ、私はFileNotFoundExceptions
を得ていた今私のProxy
クラスには、次のようになりますこの:
public IFoo GetInstanceOf(Type type)
{
var name = type.FullName;
var foo = proxy.GetInstanceOf(name);
return foo;
}
は当初、私は直接のタイプを渡しproxy.GetInstanceOf
を呼び出そうとしましたが、それはfoはおそらく働いていませんでしたr私が持っているコードと同じ理由は動作しません。私はラインvar foo = proxy.GetInstanceOf...
ラインに着くとき、私はメッセージでArgumentException
を取得:
オブジェクト型は、型をターゲットに変換することはできません。
私はMyTest_AppDomain
でIFoo
がDefaultDomain
のようにIFoo
同じであると見なされていないため、問題があると考えているが、私はこの問題を解決する正しい方法は何であるかわかりません。
IFoo
自体が別の3番目のアセンブリで定義されていて、VSIXプロジェクトと別のドメインに読み込もうとしているアセンブリの両方が参照されていることが関係する場合があります。私はMyTest_AppDomain
と同じ場所にあるIFoo
アセンブリをDefaultDomain
と同じ位置にロードすることを確信する必要があります。そうでない場合は、同じものであることを納得させる必要があります。
注:IFoo
を実装するすべてのクラスは、抽象基盤FooBase
から継承し、それ自体はMarshalByRefObject
から継承されます。
編集私の問題はここから来るかもしれない。この詳細を考える:
_assembly = Assembly.LoadFile(assemblyPath);
assemblyPath
がApplicationBase
に異なるパスがあるとIFoo
が定義されている場所、そのパスが(foo.dll
のそれ自身のバージョンを持っています)。それで、ロードする前にそこから読み込んでいますか?ApplicationBase
?Proxy.GetInstanceOf
私はtypeof(IFoo).Assembly.Location
を見ることができ、それはApplicationBase
に設定されている予想されるパスを与えますが、私のアセンブリがロードされると、そこからfoo.dll
が得られるとは思いません。
IFooをリファレンスでベースにしたいのですか、またはアプリケーションドメインで新しいコピーを期待しますか?あなたはすでにMarshalByRefで前者をやっているので、新しいコピーが必要だと思っています。 IFooによって実装されているものはすべてシリアル化可能であることを確認してください。インスタンスはシリアル化され、アプリケーションドメインをまたいで逆シリアル化されるべきです。 – Igor
@Igor:新しいアプリケーションドメインにインスタンスを作成し、そのドメインへの参照をデフォルトのドメインに渡して、メソッドを呼び出していくつかのイベントに登録できるようにしたいと思います。 –
動作しません(デフォルト)。アプリケーションドメインは、.Netリモーティングを使用して相互に通信します。アプリケーションドメイン間で受け渡されるインスタンスは基本的にコピーです。 'IFoo'を返すと、他のアプリケーションドメインで作成されたインスタンスへの参照ではなく' IFoo'のコピーが得られます(デフォルトでは)ので、IFooのイベントやメソッドを呼び出すことができず、それらのメソッドを処理するアプリケーションドメインを作成しました。 (もっと来る...) – Igor