성전으로 진출 할 위험에 처해있는이 인기있는 DI / IoC 프레임 워크의 강점과 약점은 무엇이며 쉽게 최고로 간주 될 수 있습니까? .. :
- 닌 젝트
- 통일
- Castle.Windsor
- 오토 팩
- 구조도
여기에 나열되지 않은 다른 C # 용 DI / IoC 프레임 워크가 있습니까?
유스 케이스와 관련하여 클라이언트 WPF 앱과 WCF / SQL 서비스 인프라, 사용 편의성 (특히 명확하고 간결한 구문 측면에서), 일관된 문서, 우수한 커뮤니티 지원 및 성능이 모두 중요한 요소입니다. 내 선택에.
최신 정보:
인용 된 자료와 중복 된 질문이 오래된 것 같습니다. 이러한 모든 프레임 워크에 대한 지식을 가진 사람이 앞으로 나와 실제 통찰력을 제공 할 수 있습니까?
나는이 주제에 대한 대부분의 의견이 편향 될 가능성이 있다는 것을 알고 있지만, 누군가가이 모든 프레임 워크를 연구하는 데 시간이 걸리고 적어도 일반적으로 객관적인 비교를하기를 희망합니다.
이전에이 작업을 수행하지 않은 경우 자체 조사를 수행 할 의향이 있지만 적어도 몇 사람이 이미 수행 한 것으로 가정했습니다.
두 번째 업데이트 :
하나 이상의 DI / IoC 컨테이너에 대한 경험이있는 경우 해당 장단점을 평가하고 요약하십시오. 감사합니다. 이것은 사람들이 만든 모호한 작은 컨테이너를 모두 발견하는 연습이 아니며, 인기 있고 활동적인 프레임 워크 간의 비교를 찾고 있습니다.
답변
이 질문에 대한 종합적인 답변은 제 책 의 수백 페이지를 차지하지만, 여전히 작업중인 빠른 비교 차트는 다음과 같습니다.
답변
다른 성능 비교 (2014 년 4 월 10 일 최신 업데이트)를 발견했습니다. 다음을 비교합니다.
다음은 게시물의 간략한 요약입니다.
결론
Ninject는 확실히 가장 느린 컨테이너입니다.
MEF, LinFu 및 Spring.NET은 Ninject보다 빠르지 만 여전히 느립니다. AutoFac, Catel 및 Windsor가 이어지고 StructureMap, Unity 및 LightCore가 이어집니다. Spring.NET의 단점은 XML로만 구성 할 수 있다는 것입니다.
SimpleInjector, Hiro, Funq, Munq 및 Dynamo는 최고의 성능을 제공하며 매우 빠릅니다. 그들에게 시도하십시오!
특히 Simple Injector가 좋은 선택 인 것 같습니다. 매우 빠르며 문서가 훌륭하며 차단 및 일반 데코레이터와 같은 고급 시나리오도 지원합니다.
Common Service Selector Library를 사용 해보고 여러 옵션을 시도해보고 자신에게 가장 적합한 것을 볼 수도 있습니다.
사이트에서 Common Service Selector 라이브러리에 대한 일부 정보 :
라이브러리는 IoC 컨테이너 및 서비스 로케이터에 대한 추상화를 제공합니다. 라이브러리를 사용하면 애플리케이션이 하드 참조에 의존하지 않고 기능에 간접적으로 액세스 할 수 있습니다. 이 라이브러리를 사용하면 타사 응용 프로그램과 프레임 워크가 특정 구현에 연결되지 않고 IoC / 서비스 위치를 활용할 수 있습니다.
최신 정보
2011 년 9 월 13 일 : Funq 및 Munq 가 참가자 목록에 추가되었습니다. 차트도 업데이트되었으며 성능이 저하되어 Spring.NET이 제거되었습니다.
04.11.2011 : ” Simple Injector 추가 , 성능은 모든 참가자 중 최고입니다”.
답변
그냥이 위대한 읽어 닷넷 DI 컨테이너 비교 블로그 필립 매트로합니다.
그는 철저한 성능 비교 테스트를 수행합니다.
그는 작고 빠르며 사용하기 쉬운 Autofac 을 권장 합니다 … 동의합니다. 그의 테스트에서 Unity 와 Ninject 가 가장 느린 것으로 보입니다 .
답변
면책 조항 : 2015 년 초 현재 Jimmy Bogard 의 IoC 컨테이너 기능 을 크게 비교 한 내용은 다음과 같습니다.
비교 된 컨테이너 :
- 오토 팩
- 닌 젝트
- 간단한 인젝터
- 구조도
- 통일
- 윈저
시나리오는 다음과 같습니다. IMediator 인터페이스가 있습니다. 여기에서 단일 요청 / 응답 또는 알림을 여러 수신자에게 보낼 수 있습니다.
public interface IMediator
{
TResponse Send<TResponse>(IRequest<TResponse> request);
Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request);
void Publish<TNotification>(TNotification notification)
where TNotification : INotification;
Task PublishAsync<TNotification>(TNotification notification)
where TNotification : IAsyncNotification;
}
그런 다음 기본 요청 / 응답 / 알림 세트를 작성했습니다.
public class Ping : IRequest<Pong>
{
public string Message { get; set; }
}
public class Pong
{
public string Message { get; set; }
}
public class PingAsync : IAsyncRequest<Pong>
{
public string Message { get; set; }
}
public class Pinged : INotification { }
public class PingedAsync : IAsyncNotification { }
제네릭에 대한 컨테이너 지원과 관련하여 몇 가지 사항을 살펴보고 싶습니다.
- 오픈 제네릭 설정 (IRequestHandler <,> 쉽게 등록)
- 공개 제네릭의 복수 등록을위한 설정 (두 개 이상의 INotificationHandlers)
일반 분산 설정 (기본 INotification / 생성 요청 파이프 라인에 대한 처리기 등록) 처리기는 매우 간단하며 콘솔에 출력됩니다.
public class PingHandler : IRequestHandler<Ping, Pong> { /* Impl */ }
public class PingAsyncHandler : IAsyncRequestHandler<PingAsync, Pong> { /* Impl */ }
public class PingedHandler : INotificationHandler<Pinged> { /* Impl */ }
public class PingedAlsoHandler : INotificationHandler<Pinged> { /* Impl */ }
public class GenericHandler : INotificationHandler<INotification> { /* Impl */ }
public class PingedAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ }
public class PingedAlsoAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ }
오토 팩
var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterAssemblyTypes(typeof (IMediator).Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof (Ping).Assembly).AsImplementedInterfaces();
- 오픈 제네릭 : 예, 암시 적으로
- 여러 개의 열린 제네릭 : 예, 암시 적으로
- 일반적인 모순 : 예, 명시 적
닌 젝트
var kernel = new StandardKernel();
kernel.Components.Add<IBindingResolver, ContravariantBindingResolver>();
kernel.Bind(scan => scan.FromAssemblyContaining<IMediator>()
.SelectAllClasses()
.BindDefaultInterface());
kernel.Bind(scan => scan.FromAssemblyContaining<Ping>()
.SelectAllClasses()
.BindAllInterfaces());
kernel.Bind<TextWriter>().ToConstant(Console.Out);
- 오픈 제네릭 : 예, 암시 적으로
- 여러 개의 열린 제네릭 : 예, 암시 적으로
- 일반적인 반동 : 예, 사용자 작성 확장
간단한 인젝터
var container = new Container();
var assemblies = GetAssemblies().ToArray();
container.Register<IMediator, Mediator>();
container.Register(typeof(IRequestHandler<,>), assemblies);
container.Register(typeof(IAsyncRequestHandler<,>), assemblies);
container.RegisterCollection(typeof(INotificationHandler<>), assemblies);
container.RegisterCollection(typeof(IAsyncNotificationHandler<>), assemblies);
- 오픈 제네릭 : 예, 명시 적으로
- 여러 개의 열린 제네릭 : 예, 명시 적으로
- 일반적인 모순 : 예, 암시 적으로 (업데이트 3.0 사용)
구조도
var container = new Container(cfg =>
{
cfg.Scan(scanner =>
{
scanner.AssemblyContainingType<Ping>();
scanner.AssemblyContainingType<IMediator>();
scanner.WithDefaultConventions();
scanner.AddAllTypesOf(typeof(IRequestHandler<,>));
scanner.AddAllTypesOf(typeof(IAsyncRequestHandler<,>));
scanner.AddAllTypesOf(typeof(INotificationHandler<>));
scanner.AddAllTypesOf(typeof(IAsyncNotificationHandler<>));
});
});
- 오픈 제네릭 : 예, 명시 적으로
- 여러 개의 열린 제네릭 : 예, 명시 적으로
- 일반적인 모순 : 예, 암시 적으로
통일
container.RegisterTypes(AllClasses.FromAssemblies(typeof(Ping).Assembly),
WithMappings.FromAllInterfaces,
GetName,
GetLifetimeManager);
/* later down */
static bool IsNotificationHandler(Type type)
{
return type.GetInterfaces().Any(x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(INotificationHandler<>) || x.GetGenericTypeDefinition() == typeof(IAsyncNotificationHandler<>)));
}
static LifetimeManager GetLifetimeManager(Type type)
{
return IsNotificationHandler(type) ? new ContainerControlledLifetimeManager() : null;
}
static string GetName(Type type)
{
return IsNotificationHandler(type) ? string.Format("HandlerFor" + type.Name) : string.Empty;
}
- 오픈 제네릭 : 예, 암시 적으로
- 다중 공개 제네릭 : 예, 사용자 빌드 확장 기능
- 일반적인 모순 : derp
윈저
var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
- 오픈 제네릭 : 예, 암시 적으로
- 여러 개의 열린 제네릭 : 예, 암시 적으로
- 일반적인 반 공예 : 예, 사용자 작성 확장
답변
실제로 수많은 IoC 프레임 워크가 있습니다. 모든 프로그래머가 경력의 어느 시점에서 하나를 쓰려고하는 것 같습니다. 아마도 그것을 출판하지 말고 내면의 일을 배우십시오.
autofac은 매우 유연하고 나에게 맞는 구문을 가지고 있기 때문에 개인적으로 선호합니다 (모든 레지스터 메소드가 확장 메소드라는 것을 정말로 싫어하지만).
다른 프레임 워크 :
답변
글쎄, 지금까지 내가 찾은 최고의 비교를 살펴본 결과는 다음과 같습니다.
-
http://www.sturmnet.org/blog/2010/03/04/poll-ioc-containers-for-net
-
http://www.sturmnet.org/blog/2010/03/04/poll-results-ioc-containers-for-net
2010 년 3 월에 실시 된 여론 조사입니다.
DI / IoC 프레임 워크를 사용하고 마음에 들거나 싫어하는 사람들이 StructureMap을 사용하는 것으로 나타났습니다.
또한 여론 조사에서 Castle.Windsor 와 StructureMap 이 가장 선호되는 것 같습니다.
흥미롭게도 Unity 와 Spring.Net 은 가장 일반적으로 싫어하는 인기있는 옵션 인 것 같습니다. (나는 게으름에서 Unity를 고려하고 있었고 Microsoft 배지 / 지원), 지금 Castle Windsor와 StructureMap을 더 자세히 살펴볼 것입니다.
물론 이것은 아마도 (?) 2010 년 5 월에 릴리스 된 Unity 2.0에는 적용되지 않습니다.
다른 누군가가 직접적인 경험을 바탕으로 비교를 할 수 있기를 바랍니다.
답변
이 텍스트를 작성하는 동안 목록에없는 linfu 및 spring.net을 포함한 Google 코드 의 net-ioc-frameworks 비교를 참조하십시오 .
나는 spring.net으로 일했다 : 그것은 많은 기능 (aop, 라이브러리, docu 등)을 가지고 있으며 닷넷과 자바 세계에서 많은 경험이있다. 기능은 모듈화되어 있으므로 모든 기능을 사용할 필요는 없습니다. 이 기능은 데이터베이스 요약, 로깅 요약과 같은 일반적인 문제의 추상화입니다. 그러나 IoC 구성을 수행하고 디버깅하기가 어렵습니다.
내가 지금까지 읽은 것에서 : 중소 프로젝트를 선택해야한다면 ioc 구성이 완료되고 c #에서 디버깅 할 수 있기 때문에 ninject를 사용합니다. 그러나 나는 아직 그것을 사용하지 않았습니다. 대형 모듈 시스템의 경우 추상화 라이브러리 때문에 spring.net을 유지합니다.