C# Appdomain의 동적 dll 교체 무시
3133 단어 설계의 아름다움
그러나 참조 DLL이 있는 경우인용된 프로그램 집합을 어떻게 해제하는지 기본적으로 곤경에 빠졌다.
인터넷 자료는 앱domain이 해결할 수 있는 것이 아니다.그러나 성능 손실을 제외하고는 호출 방식이 불편하다.
이런 번거로운 해결 방안은 그렇지 않으면 자주 프로젝트에서 실시되지 않을 것이다.
물론 처음부터 설계에 치중해 공장 용기를 도입해 대상관리 같은 항목은 제외했다.
여기, 우리가 작은 프로젝트를 보여 드리겠습니다. 아마도, 당신에게 도움이 될 것입니다.
우선: Assembly Resolve
Assembly를 사용해 보시오.Load가 프로그램 집합을 불러오고 그 방법을 실행하려고 시도할 때다른 프로그램 집합을 인용하는 경우 Assembly Resolve가 등장합니다.
너는 이렇게 그것을 사용할 수 있다.
static List AssemblyList = new List();
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
foreach (var item in AssemblyList)
{
if (item.ToString() == args.Name)
{
return item;
}
}
return null;
}
프로그램이 그곳에 집합되어 있든지 간에,loader 디렉터리에 두지 마십시오.
우선 프로그램 집합을 다시 정하는 것이 우선입니다. 이 단계는 우리가 이미 끝냈습니다.(밑에 계란 깨고 내려가, 이런 식으로..., 압력을 견디고 건물주가 계속...)
알겠습니다. 그리고 프로그램 집합 잠금에 대한 질문입니다. 이렇게.
AssemblyList.Add(Assembly.Load( System.IO.File.ReadAllBytes(item.FullName)));
그 다음이야말로 중요한 장면이다. dll을 어떻게 해제하는지(잠이 들 것 같아...)
다음은 위조 코드입니다. 꼭 뛸 수 있는 것은 아닙니다. 그런 뜻을 보십시오.
DLL A:
public class ClassA
{
public ClassA()
{
Console.WriteLine("나는 A다");
}
}
보존하고 방사능을 통해 호출한다.이거 문제 없지.
byte[] buffer = System.IO.File.ReadAllBytes(@"lib1.dll"); System.Reflection.Assembly.Load(buffer).CreateInstance("ClassA");
ok, 첫걸음 완성, 강화 아래,
DLL B:
public class ClassB
{
public ClassB()
{
Console.WriteLine("나는 B다");
}
public void TestB()
{
Console.WriteLine("TestB");
}
}
DLLA 수정
public ClassA()
{
Console.WriteLine("나는 A다");
Console.WriteLine("DLLB 실행");
new ClassB().TestB();
}
다시 반사 운행, ok 문제없습니다.
그리고 다시 한 번, 당신은 당신의 운행 코드를 수정하고 순환을 넣어야 합니다. 이렇게:
while(true)
{
byte[] buffer = System.IO.File.ReadAllBytes(@"lib1.dll"); System.Reflection.Assembly.Load(buffer).CreateInstance("ClassA");
Thread.Sleep(3000);
}
3초에 한 번씩 호출해서 그가 독립적으로 운행하도록 해라.
그리고 실행할 때 DLLA를 수정합니다.
public ClassA()
{
Console.WriteLine("나는 A야, 동적 수정...");
}
컴파일하고 돌아와서 테스트 프로그램을 보니 별 문제가 없을 것 같다.(다들 계속 계란... 쓸데없는 소리...)
DLLB 수정
Console.WriteLine("나는 B, 동적 운행");
컴파일, 계속 테스트를 보세요.변한 게 없는 것 같습니다.
중점이 왔다. 여기가 바로 우리가 해결해야 할 문제다.
Assembly Resolve 메서드를 추적하면 두 번째 로드 시 트리거되지 않았음을 알 수 있습니다.
즉, dllb는 계속 메모리에 있습니다. 어떻게 마운트를 해제하는지, 솔직히 말해서 저도 마운트를 해제하지 않습니다. (사람들이 화를 내며 내려가세요...)
하지만 우리는 바꿀 수 있다.(그럭저럭, 안 되면 찍어버릴 거야.)
우리가 고쳐야 할 것은 단지 조금뿐입니다. dllb의 버전 번호를 수정한 다음에 dlla와 dllb를 다시 컴파일합니다.
그리고 만약 의외의 일이 발생하지 않는다면, 당신은 이미 테스트 프로그램에서 당신이 원하는 결과를 보았을 것이다.
(모두들, 더 말하면 끝이잖아. 쓸데없는 소리 하지 말고 계속 계란 시중을 들어. 계란이 비싸잖아. 잃어버리지 마.)
감사합니다.