2009-09-10 3 views
5

NDC에서 Bob Martin의 에피소드를 끝 마쳤습니다. 페이지 맨 위에있는 C#의 "using"지시문은 구성 요소 간의 긴밀한 결합으로 인해 잘못되었습니다.C#에서 "using"지시문 키워드 대신 사용할 수있는 방법은 무엇입니까?

프로젝트 참조 및 using 문을 추가하지 않고 외부 .dll을 사용하는 방법은 무엇입니까?

나는 V6을 사용하여 ProgId 문자열로 객체를 만들었다는 것을 기억한다. 내가 찾고있는 기술은 확실하지 않지만 프로젝트가 필요없는 언어의 예이다. DLL을 사용하는 참조.

편집 : Here is a link to the conference. 프리젠 테이션에 정확한 인용문이나 분이 없어 죄송합니다. 기억에 남을 것입니다.

+1

정말로 말 했나요? 아니면 그가 말한 것을 이해 했나요? –

+3

이 링크는 도움이 될 것입니다. 그가 실제로 말한 것을 듣고 싶습니다. – tvanfosson

+6

혼동을 피하기 위해 Microsoft는이를 "지시문"이라고 부릅니다. using 문 (키워드)은 일반적으로 리소스 내에서 Dispose를 자동으로 호출하는 메서드 내에서 사용되는 문을 참조합니다. – Ash

답변

6

이 아니에요 나쁜 using 문 자체 - 당신이 그들의 너무 많은를 얻는 경우가 있습니다.

using System;과 같은 문구는 그 자체로는 거의 문제가되지 않지만, 동일한 코드 파일에서 많은 것들이 있다면 (나는 3-6 개 이상을 말할 것입니다), 일 수 있습니다. 타이트 커플 링.

프로젝트 자체의 참조 수와 비슷한 방식으로 적용 할 수 있습니다.

단단 결합에 대한 해결책은 및 DI (Dependency Injection) 인터페이스에 프로그래밍하는 것입니다 ().

VB에서 기억할 수있는 일을하는 ProgId 방식은 COM 작동 방식이었습니다. 본질적으로, ProgId를 사용하여 원하는 인터페이스를 구현 한 인스턴스에 대한 참조를 얻었습니다. 단점은 COM 개체가 보편적으로 등록되었을 때만 작동한다는 것입니다. dll을 기억하니?

특정 유형의 DI를 사용하여 동일한 원칙을 적용 할 수 있습니다. 인터페이스는 .NET 유형이며 IDL에 정의되어 있지 않으며 구체적인 구현을 제공하는 일종의 DI 컨테이너가 필요합니다.

+1

필자는 이것을 "쓸데없는 커플 링의 표시 일 수 있습니다 **"** "밀접한 커플 링의 ** 표시 일 수 있다면 **" –

+0

@ Vinko Vrsalovic : 아니오, 동의하지 않습니다 : If 당신은 20 개의 진술을 사용하고 있습니다. 그것은 단단한 결합의 확실한 표시입니다. –

+0

다음과 같이 말하십시오. "단단한 커플 링 ** 표시 ** –

6

using은 외부 파일에 대한 참조가 아니라 이름 공간의 바로 가기입니다. 따라서 이것은 실제로 의미가 없습니다.

어쨌든 인터페이스 DLL (인터페이스 만있는 DLL)을 사용하면 동적 어셈블리를로드하고 다른 어셈블리를 사용하고 잘 알려진 인터페이스로 캐스팅 할 수있는 리플렉션을 통해 유형을 만들 수 있습니다. 이것은 강력한 형식의 언어와 초기 바인딩의 이점을 유지하면서 외부 참조를 느슨하게하는 적절한 방법입니다.

AssemblyAppDomain 어셈블리를로드하는 클래스와 Activator을 참조하여 유형 인스턴스를 이름으로 작성하십시오.

+6

동의. 진술을 잘못 사용한다고 말하는 사람은 그가 무슨 말을하는지 분명히 알지 못합니다. – Noldorin

+4

@ Noldorin : 로버트 C. 마틴 그가 무슨 말하는지 모르겠다! –

+1

또는 그는 오해 받았다. 있었거나 잘못 된 사람은별로 중요하지 않습니다. 왜냐하면 "받은 메시지"가 의미가 없기 때문입니다. – Lucero

7

저는 Bob Martin이 실제로 초기 바인딩과 후기 바인딩을 언급하고 있다고 생각합니다.

.NET에서 후기 바인딩은 파일 이름 또는 어셈블리 이름을 사용하여 외부 어셈블리에 형식을 만들 수있는 Activator 클래스를 통해 가능합니다.

일반적으로 지시문을 사용하면 (using 문이 아닌) 직접 외부 어셈블리를 참조 할 수 있습니다. 즉. 어셈블리에 대한 참조를 추가 한 다음 지시문을 사용하여 외부 형식을 사용할 때 전체 네임 스페이스 계층 구조를 입력하지 않아도됩니다.

코드에 맨 위에 사용 지시문이 많이있는 경우 다른 많은 유형을 직접 참조하므로 이러한 유형에 대한 코드의 결합/종속성이 높아질 수 있습니다.

나는 Bob이 그들을 나쁜 것으로 언급하는 이유가 무엇인지 추측 할 것입니다. 이 질문에 대한 대답은 "실제로 이것은 나쁜 것인가?" 매우 주관적이고 상황에 따라 다릅니다.

그러나 일반적으로 구성 요소의 디 커플 링은 소프트웨어 설계를 목표로하는 거의 항상 좋은 목표입니다. 시스템의 나머지 부분에 미치는 영향을 최소화하면서 시스템의 일부분을 변경할 수 있기 때문입니다. Bob Martins 서적 중 한두 권을 읽었을 때, 나는 이것이 그가 무엇을 얻고 있는지를 기대할 것입니다.

1

리플렉션을 통해 당신이 말하는 것을 할 수 있습니다. 런타임에 어셈블리를로드하고이를 통해 클래스 등을 가져 와서 동적으로 호출 할 수 있습니다.

개인적으로는 커플 링을 피하기 위해 개인적으로는하지 않겠습니다. 내게 반성의 나쁜 사용이고, 그렇게하지 않는 특별한 이유가 없다면, 나는 그것을 프로젝트에 추가하고 그것을 참조하기를 훨씬 좋아할 것이다. 리플렉션은 시스템에 오버 헤드를 추가하고 컴파일 시간 안전의 이점을 얻지 못합니다.

+0

또한이 "기술"*은 커플 링을 피할 수 없습니다. DLL을 동적으로 호출하기 때문에 코드가 외부 DLL에 덜 결합되지 않습니다. DLL이 없으면 코드가 작동하지 않습니다. – MusiGenesis

+1

인터페이스 어셈블리가 있고 인터페이스가있는 동적으로 개체를로드하면 연결이 줄어 듭니다. 의존성 주입도 좋은 접근법입니다. – kenny

+0

@Kenny : 당신은 그럴 권리가 있습니다. 나는 참조를 제거하고 대신 동적으로로드하는 경우 상황을 개선하지 않는다는 점을 더욱 강조했습니다. – MusiGenesis

2

당신은 반사를 사용할 수 있습니다

// Load the assembly 
Assembly assembly = Assembly.LoadFrom(@"c:\path\Tools.dll"); 
// Select a type 
Type type = assembly.GetType("Tools.Utility"); 
// invoke a method on this type 
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]); 
+4

이 호출 종류는 후기 바인딩이라고하며 느리고 오류가 발생하기 쉽지만 런타임에 바인딩을 즉시 지원할 수 있도록 설계되지 않은 C#과 같은 언어에서는 (예 : 컴파일러 마술을 통해) 매우 번거롭습니다. 가능하면이 방법을 피하십시오. – Lucero

+0

솔직히 이런 종류의 DI 프레임 워크를 사용하는 것이 더 좋습니다. noobish를 위해서도 좋습니다. – Will

관련 문제