문제

이 질문은 구조 맵과 관련이 있지만 내 일반 질문은 다음과 같습니다.

IOC 컨테이너로 구성 요소를 배선 할 때 코드에서 (이를 통해 구성하는 것과 반대로 XML) 일반적으로 모든 어셈블리에 대한 명시적인 프로젝트/빌드 참조가 필요합니까?

왜 별도의 어셈블리인가? 왜냐하면:


"구체적인 구현에서 별도의 어셈블리에 거주하는 추상 클래스는 그러한 분리를 달성하는 좋은 방법입니다." -프레임 워크 설계 지침 p.91


예시:

내가 가지고 있다고 가정 해 봅시다 personbase.dll 그리고 bob.dll

단발 추상 클래스에서 상속합니다 인력베이스. 둘 다 안에 있습니다 사람 네임 스페이스. 그러나 다른 어셈블리에서.

나는 프로그래밍하고있다 인력베이스, 아니다 단발.

내 주요 코드로 돌아가서 사람이 필요합니다. StructureMap은 어셈블리를 스캔 할 수 있습니다. 좋아, 나는 구조를 물어 보겠다!

이제 내 주요 코드에서는 물론 인력베이스, 그렇지 않습니다 단발. 나는 실제로 내 코드가 알고 싶지 않습니다 아무것 ~에 대한 단발. 프로젝트 참조, Nuthin이 없습니다. 그것이 요점입니다.

그래서 나는 말하고 싶다 :

//Reference: PersonBase.dll (only)
using Person;  
...

//this is as much as we'll ever be specific about Bob:
Scan( x=> { x.Assembly("Bob.dll"); }

//Ok, I should now have something that's a PersonBase (Bob). But no ?
ObjectFactory.GetAllInstances<PersonBase>().Count == 0

불운. 일은 내가 밥을 원한다는 명시 적입니다.

//Reference: PersonBase.dll and Bob.dll
using Person; 
...
Scan( x => {x.Assembly("Bob.dll"); }

//If I'm explicit, it works. But Bob's just a PersonBase, what gives?
ObjectFactory.GetAllInstances<Bob>().Count == 1 //there he is!

그러나 지금 나는 참조해야했다 bob.dll 내 프로젝트에서 바로 내가 원하지 않는 것입니다.

스프링 + XML 구성을 사용 하여이 상황을 피할 수 있습니다. 그러나 나는 Spring + XML 구성으로 돌아 왔습니다 ...!

structuremap을 사용하거나 일반적인 원칙으로 무언가를 놓치고 있습니까?

관련 질문 : 구조 맵 및 스캐닝 어셈블리

도움이 되었습니까?

해결책

나는 마침내 이것을 분류했다. 다음과 같이 보입니다.

IOC UML http://img396.imageshack.us/img396/1343/iocuml.jpg

어셈블리와 함께

  • Core.exe
  • personbase.dll (참조 시간을 컴파일하십시오 by core.exe)
  • bob.dll (실행 시간을로드했습니다 StructureMap 스캔을 통해)
  • Betty.dll (실행 시간을로드했습니다 StructureMap 스캔을 통해)

StructureMap을 사용하려면 어셈블리 스캔을 지원하기 위해 사용자 정의 "itypescanner"가 필요했습니다.

public class MyScanner : ITypeScanner {
  public void Process(Type type, PluginGraph graph) {

    if(type.BaseType == null) return;

    if(type.BaseType.Equals(typeof(PersonBase))) {
      graph.Configure(x => 
        x.ForRequestedType<PersonBase>()
        .TheDefault.Is.OfConcreteType(type));
    }
  }
} 

그래서 내 주요 코드는 다음과 같습니다.

ObjectFactory.Configure(x => x.Scan (
  scan =>
  {
    scan.AssembliesFromPath(Environment.CurrentDirectory 
    /*, filter=>filter.You.Could.Filter.Here*/);

    //scan.WithDefaultConventions(); //doesn't do it

    scan.With<MyScanner>();
  }
));

ObjectFactory.GetAllInstances<PersonBase>()
 .ToList()
  .ForEach(p => 
  { Console.WriteLine(p.FirstName); } );

다른 팁

StructureMap을 사용하여 XML 구성을 수행 할 수도 있습니다. 원하는 경우 섞을 수도 있습니다.

Bob 클래스에 넣을 수있는 구조적 속성도 있습니다. DefaultConstructor는 때때로 내가 사용하게 된 것입니다.

자동 스캔 옵션은 명명, 어셈블리 및 네임 스페이스 규칙을 유지할 때만 작동합니다. 유창한 인터페이스로 StructureMap을 수동으로 구성 할 수 있습니다. 예시:

ObjectFactory.Initialize(initialization => 
   initialization.ForRequestedType<PersonBase>()
    .TheDefault.Is.OfConcreteType<Bob>());

현재 프로젝트에서 수행하는 일 (구조 맵이 아닌 AutoFac을 사용하지만 차이를 만들어서는 안된다고 생각합니다) :

응용 프로그램이 핵심 어셈블리에서 사용하는 외부 서비스를 정의하는 인터페이스가 있습니다. App.Core (개인베이스처럼).

그런 다음 이러한 인터페이스의 구현이 있습니다 Services.Real (bob.dll처럼).

우리의 경우에도 우리에게도 있습니다 Service.Fake, 다른 엔터프라이즈 서비스 및 데이터베이스 등에 대한 의존성으로 UI 테스트를 용이하게하는 데 사용됩니다.

프론트 엔드 "클라이언트"응용 프로그램 자체 (이 경우 ASP.NET MVC 앱) 참조 App.Core.

앱이 시작되면 사용합니다 Assembly.Load 구성 설정을 기반으로 적절한 "서비스"구현 DLL을로드합니다.

이러한 각 DLL은 ISSERVICEREGISTRY를 구현하여 IT가 구현하는 서비스 목록을 반환합니다.

public enum LifestyleType { Singleton, Transient, PerRequest}

public class ServiceInfo {
    public Type InterfaceType {get;set;}
    public Type ImplementationType {get;set;}
    // this might or might not be useful for your app, 
    // depending on the types of services, etc.
    public LifestyleType Lifestyle {get;set;} 
}

public interface IServiceRegistry {
    IEnumerable<ServiceInfo> GetServices();
}

... 응용 프로그램은 반사를 통해이 서비스 요법을 찾아이 서비스 인스턴스를 통해 열거하고 컨테이너에 등록합니다. 우리에게는이 레지스터-서비스는 웹 응용 프로그램에 살고 있지만 별도의 어셈블리에 넣을 수 있습니다.

이런 식으로 우리는 인프라 코드에서 도메인 로직을 분리하고 인프라 코드에 대한 직접 참조에 따라 응용 프로그램이 끝나는 "Just-Once"워크 어라운드를 방지 할 수 있습니다. 또한 각 서비스 구현에서 컨테이너를 참조 할 필요가 없습니다.

이 작업을 수행하는 경우 정말 중요한 것 : 확실한 IOC 컨테이너의 각 잠재적 구성으로 각 "최상위"유형 (ASP.NET MVC 컨트롤러)을 작성할 수 있는지 확인하는 테스트가 있습니다.

그렇지 않으면 하나의 인터페이스를 구현하고 응용 프로그램의 거대한 섹션을 깨뜨리는 것을 잊기 쉽습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top