Bunu birkaç kez yapmak zorunda kaldım ve birçok farklı çözümü araştırdım.
En zarif ve gerçekleştirmesi kolay bulduğum çözüm bu şekilde uygulanabilir.
1. Basit bir arayüz oluşturabileceğiniz bir proje oluşturun
arayüz aramak istediğiniz tüm üyelerin imzalarını içerecektir.
public interface IExampleProxy
{
string HelloWorld( string name );
}
Bu projeyi temiz ve hafif tutmak önemlidir. Her ikisinin AppDomain
de referans verebileceği ve Assembly
müşteri derlememizden ayrı etki alanına yüklemek istediğimizi referans vermememize izin verecek bir projedir .
2. Şimdi ayrı olarak yüklemek istediğiniz kodun bulunduğu bir proje oluşturun AppDomain
.
İstemci projesinde olduğu gibi bu proje, proxy projesine referans verecek ve arayüzü uygulayacaksınız.
public interface Example : MarshalByRefObject, IExampleProxy
{
public string HelloWorld( string name )
{
return $"Hello '{ name }'";
}
}
3. Daha sonra, istemci projesinde, kodu başka bir projeye yükleyin AppDomain
.
Şimdi yeni bir tane yaratıyoruz AppDomain
. Montaj referansları için temel konumu belirleyebilir. İnceleme, GAC'deki ve geçerli dizindeki ve AppDomain
temel loc'daki bağımlı derlemeleri kontrol edecektir .
// 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 );
Gerekirse, bir montajı yüklemenin tonlarca farklı yolu vardır. Bu çözümle farklı bir yol kullanabilirsiniz. Derleme nitelikli isme sahipseniz CreateInstanceAndUnwrap
, derleme baytlarını yüklediği ve ardından sizin için türünüzü object
başlattığı ve proxy türünüze basitçe çevirebileceğiniz bir döndürdüğü için veya bunu güçlü bir şekilde yazılmış koda sahip değilseniz bunu kullanmayı seviyorum dinamik dil çalışma zamanını kullanın ve döndürülen nesneyi dynamic
yazılı bir değişkene atayın, ardından üyeleri doğrudan bu değişkene çağırın.
İşte aldın.
Bu, istemci projenizin ayrı bir referansa sahip olmadığı bir derlemeyi yüklemenize ve istemciden AppDomain
üyeler çağırmanıza olanak tanır .
Test etmek için Visual Studio'da Modüller penceresini kullanmayı seviyorum. Size istemci derleme etki alanınızı ve bu etki alanında hangi tüm modüllerin yüklendiğini, ayrıca yeni uygulama etki alanınızı ve bu etki alanında hangi derlemelerin veya modüllerin yüklü olduğunu gösterir.
Anahtar, kodunuzun türetildiğinden MarshalByRefObject
veya serileştirilebilir olduğundan emin olmaktır .
`MarshalByRefObject, içinde bulunduğu etki alanının yaşam süresini yapılandırmanıza olanak tanır. Örneğin, proxy 20 dakika içinde çağrılmadıysa etki alanının yok edilmesini istediğinizi varsayalım.
Umarım bu yardımcı olur.