Musiałem to zrobić kilka razy i zbadałem wiele różnych rozwiązań.
Rozwiązanie, które uważam za najbardziej eleganckie i łatwe do wykonania, można zaimplementować jako takie.
1. Utwórz projekt, w którym możesz stworzyć prosty interfejs
interfejs będzie zawierał podpisy wszystkich członków, do których chcesz zadzwonić.
public interface IExampleProxy
{
string HelloWorld( string name );
}
Ważne jest, aby projekt był czysty i lekki. Jest to projekt, do którego oba AppDomain
mogą się odwoływać i który pozwoli nam nie odwoływać się do tego, Assembly
który chcemy załadować w oddzielnej domenie z naszego zestawu klienta.
2. Teraz utwórz projekt zawierający kod, który chcesz załadować oddzielnie AppDomain
.
Ten projekt, podobnie jak w przypadku projektu klienta, będzie odnosił się do projektu proxy i zaimplementujesz interfejs.
public interface Example : MarshalByRefObject, IExampleProxy
{
public string HelloWorld( string name )
{
return $"Hello '{ name }'";
}
}
3. Następnie w projekcie klienta załaduj kod do innego AppDomain
.
Więc teraz tworzymy nowy AppDomain
. Może określić lokalizację podstawową dla odniesień do zestawów. Sondowanie sprawdzi zależne zestawy w GAC oraz w bieżącym katalogu i AppDomain
bazowym locie.
// set up domain and create
AppDomainSetup domaininfo = new AppDomainSetup
{
ApplicationBase = System.Environment.CurrentDirectory
};
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
AppDomain exampleDomain = AppDomain.CreateDomain("Example", adevidence, domaininfo);
// assembly ant data names
var assemblyName = "<AssemblyName>, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null|<keyIfSigned>";
var exampleTypeName = "Example";
// Optional - get a reflection only assembly type reference
var @type = Assembly.ReflectionOnlyLoad( assemblyName ).GetType( exampleTypeName );
// create a instance of the `Example` and assign to proxy type variable
IExampleProxy proxy= ( IExampleProxy )exampleDomain.CreateInstanceAndUnwrap( assemblyName, exampleTypeName );
// Optional - if you got a type ref
IExampleProxy proxy= ( IExampleProxy )exampleDomain.CreateInstanceAndUnwrap( @type.Assembly.Name, @type.Name );
// call any members you wish
var stringFromOtherAd = proxy.HelloWorld( "Tommy" );
// unload the `AppDomain`
AppDomain.Unload( exampleDomain );
jeśli zajdzie taka potrzeba, istnieje mnóstwo różnych sposobów ładowania zespołu. Z tym rozwiązaniem możesz skorzystać w inny sposób. Jeśli masz nazwę kwalifikowaną zestawu, lubię używać, CreateInstanceAndUnwrap
ponieważ ładuje bajty zestawu, a następnie tworzy dla Ciebie wystąpienie typu i zwraca object
, że możesz po prostu rzutować na typ serwera proxy lub jeśli nie, to w silnie wpisanym kodzie, możesz użyj środowiska uruchomieniowego języka dynamicznego i przypisz zwrócony obiekt do dynamic
zmiennej o typie strukturalnym, a następnie bezpośrednio wywołaj członków.
Masz to.
Pozwala to na załadowanie zestawu, do którego Twój projekt klienta nie ma odniesienia, w osobnym AppDomain
i wywołanie członków z klienta.
Aby przetestować, lubię używać okna modułów w programie Visual Studio. Pokaże Ci domenę zestawu klienta i jakie wszystkie moduły są ładowane w tej domenie, a także nową domenę aplikacji i jakie zestawy lub moduły są ładowane w tej domenie.
Kluczem jest upewnienie się, że kod pochodzi MarshalByRefObject
lub można go serializować.
`MarshalByRefObject pozwoli ci skonfigurować czas życia domeny, w której się znajduje. Przykład, powiedzmy, że chcesz, aby domena została zniszczona, jeśli serwer proxy nie został wywołany w ciągu 20 minut.
Mam nadzieję, że to pomoże.