MSDN 기사의 오류: 동적으로 플러그인 찾기

  • Post author:
  • Post category:
  • Post comments:0 Comments
  • Post last modified:March 3, 2008

Search Dynamically for Plug-Ins은 C# 기반의 플러그인 시스템을 만들 때 마주치는 문제를 지적하고, 해결법을 간략하게 소개한다. 특히 돌려볼 수 있는 예제가 있어서 좋다. 하지만 이 예제에는 치명적인 약점이 있었다.

플러그인 시스템을 구축하려면 우선 플러그인을 구현한 어셈블리가 어느 것인지 동적으로 찾아야한다. 그래서 이 예제는 지정된 폴더에 들어있는 DLL 확장자 파일을 모두 검색하고, 플러그인 타입이 있는지 확인부터 한다. 문제는 여기서부터 시작되는데, 어셈블리를 적재하려면 애플리케이션 도메인부터 새로 만들어야 한다. 한번 애플리케이션 도메인에 어셈블리를 적재하면, 어셈블리만 따로 해제(Unload)할 수 없다. 어셈블리가 적재된 애플리케이션 도메인 전체를 해제하는 수밖에 없기 때문에, 기본 애플리케이션 도메인(AppDomain::CurrentDomain)에 플러그인을 구현한 어셈블리를 적재하는 건 말도 안 된다. 기본 애플리케이션 도메인은 해제 자체를 할 수 없기 때문이다. 더욱이 플러그인을 찾으려고 어셈블리를 적재할 뿐이라 플러그인을 구현하지 않은 어셈블리도 적재될 수가 있다는 것도 문제다.

결국 플러그인을 찾을 때는 별도의 응용프로그램 도메인을 만들어 어셈블리를 적재해야 한다. 여기까지는 이 예제의 방향이 옳다. 하지만 정작 실제 구현한 코드를 보면 문제가 있다.

AppDomain domain = AppDomain.CreateDomain("PluginLoader");
PluginFinder finder =  (PluginFinder)domain.CreateInstanceFromAndUnwrap
		(Application.ExecutablePath,"Royo.PluggableApp.PluginFinder");
ArrayList FoundPluginTypes = finder.SearchPath(Environment.CurrentDirectory);

위의 코드는 호출부인데, 여기까지는 맞는 듯 하다. 별도의 애플리케이션 도메인을 만들어서 그 안에 플러그인을 찾는 객체를 생성한다. 하지만 SearchPath 안을 보면 뭔가 이상하다.

private void TryLoadingPlugin(string path)
{
	try
	{
		//Assembly asm= Assembly.LoadFile(path);
		FileInfo file = new FileInfo(path);
		path = file.Name.Replace(file.Extension,"");
		Assembly asm = AppDomain.CurrentDomain.Load(path);

		foreach(Type t in  asm.GetTypes())
		{
			foreach(Type iface in  t.GetInterfaces())
			{
				if(iface.Equals(typeof(IPlugin)))
				{
					AddToGoodTypesCollection(t);
					break;
				}
			}
		}
	}
	catch(Exception e){}
}

얼핏 보면 문제가 없지만, 사실은 AppDomain.CurrentDomain.Load가 문제다. 새 애플리케이션 도메인 안에서 TryLoadingPlugin를 호출했으니 현재 도메인이 새로 만든 도메인일거라 생각했나본데, 그건 아니다. 디버거로 확인해보면 여전히 기본 도메인(Id: 1)이 현재 도메인이란 걸 알 수 있다.

애플리케이션 도메인은 메모리 격리 모델일 뿐 스레드 모델이 아니다. 그리고 AppDomain.CurrentDomain현재 스레드에 대한 현재 응용 프로그램 도메인을 가져온다라고 MSDN에 적혀 있다. 그러니 새 애플리케이션 도메인에 어셈블리를 적재하고 싶다면, 해당 애플리케이션 도메인을 매개변수로 직접 넘겨 받아야 한다.

해결책을 간단히 설명했는데, 실제론 이것보다 복잡하다. 하여튼 응용 프로그램 도메인은 닷넷에서 가장 골치 아프고 미묘한 주제 중 하나이다.

Author Details
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments