문제

나는 여기에 매우 일반적인 상황.고 몇 년 동안 못 찾았으면 내가 무엇을 하는 것은 오른쪽으로 산업 기준입니다.을 고려하는 응용 프로그램 데이터베이스에 연결되지만 연결 문자열이 저장되는 대신에 어떤 파일 설정/로 전달되고 있으로 명령행 매개변수에서 시작하거나 데이터베이스를 열람하는 시간에 응용 프로그램을 시작합니다.

잘 그것은 필요가 저장을 연결 문자열은 어딘가 범위 내에서의 응용이다.가장 일반적인 방법으로 보았다는 것입니다 수행하는 모듈 또는 글로벌 클래스와 get/set 방법을 저장하는 연결 문자열입니다.또 다른 방법은 당신이 그것을 사용하여 단일.거나 옵션을 내 DAL 에 액세스할 수 있는 경우 연결 문자열에 필요를 통해 GetConnectionString 방법입니다.

은 거기에 더 나은 방법을 이?

업데이트: 가 없 config 파일과 심지어 내가 그랬다면 내가 필요로 연결 문자열을 읽을 수 있 한 번 생활을 위한 응용 프로그램의 인스턴스입니다.할 수 있습니에 정교한"주입하는 모든 종류"일

도움이 되었습니까?

해결책

일반적으로 글로벌 클래스 또는 싱글 톤이든 가능한 한 피해야합니다.

이상적인 솔루션은 응용 프로그램이 구성 문자열을 구성 및 주사 그것을 필요로하는 모든 클래스로. 응용 프로그램의 크기에 따라 an IOC 컨테이너와 같은 단일성 또는 성 윈저 도움이 될 수 있지만 확실히 솔루션의 필수 부분은 아닙니다.

그것이 옵션이 아니고 당신이 글로벌 상태를 유지하고 있다면 (기존 코드베이스 또는 그 밖의 무엇이든 있기 때문에, 나는 당신이 제안한 두 접근법 사이에 큰 차이가 있다는 것을 모르겠습니다.

업데이트: 명확히하기 위해, 지금 IOC 컨테이너에 대한 모든 것들을 잊어 버리십시오. "Inject"는 "매개 변수로 전달"하는 멋진 방법 일뿐입니다 (클래스의 생성자 또는 속성을 통해 또는 무엇이든).

데이터 액세스 클래스가 연결되는 대신 연결 문자열 (일종의 글로벌 또는 싱글 톤)을 요청해야합니다. 생성자 또는 속성을 통해 전달하십시오.

업데이트 #2 : 나는이 접근법이 무엇을 수반하는지에 대해 여전히 오해가 있다고 생각합니다.

기본적으로 데이터 액세스 클래스가 어떻게 보이는지 여부가 있습니다.

public class DataAccessClass
{
    public DataAccessClass()
    {
        _connString = SomeStaticThing.GetConnectionString();
    }
}

또는

public class DataAccessClass
{
    public DataAccessClass(string connString)
    {
        _connString = connString;
    }
}

이것들 조항 (실제로, 그 블로그의 많은 기사)는 후자가 전자보다 더 나은 이유를 여러 가지에 대해 자세히 설명합니다 (적어도 전자는 단위 테스트가 거의 불가능하기 때문에).

예, AT 어떤 곳 처음에는 연결 문자열을 잡을 책임이있는 정적 인력이 있어야하지만, 정적 메소드에 대한 종속성은 해당 한 지점으로 제한된다는 것입니다 (이는 프로세스의 주요 방법이 될 것입니다. 전체 코드베이스 전체에 뿌려지지 않고 응용 프로그램을 부트 스트랩하는 것).

다른 팁

그것은 너무 많은 창의적인 해결책은 간단한 문제;-)

두드러진 사실에서,OP 질문:

  1. 연결 문자열을 전달에서는 명령줄
  2. 다른 많은 구성 요소를 사용할 필요가 있을 수도 있 연결 문자열

그래서, 방법은 없습니 주위의 사용을 정적 요소;그것이 전역 변수(어렵습니다.NET,정지 않고,바깥쪽 클래스),정적 클래스고,또는 단일 중요하지 않습니다.가장 짧은 경로 솔루션이 될 것이 정체되는 클래스에 의해 초기화 프로그램 클래스가 처리되는 명령 라인입니다.

다른 모든 솔루션은 여전히 필요한 정적 접근을 전달된 연결 문자열, 지만,그들은 숨길 수 있습이 뒤에는 하나 이상의 층 간접 참조.

나는지는 말하고 싶지 않 드레스까지 기본적인 솔루션으로 뭔가 애호가이지만,그것은 필요하지 않습니다,그리고 그것을 제거하지 않는 근본적으로 정적/글로벌 자연의 연결 문자열 설명.

당신이 저장하고있는 모든 것이 문자열 (아마도 다른 글로벌 응용 프로그램 설정과 함께)이라면, 모든 것을 유지하기 위해 많은 속성이있는 정적 클래스를 사용합니다. 싱글 톤은 더 많은 코드 및 유지 보수 작업이지만이 경우 불필요한 작업입니다. 속성 클래스는 아무것도하지 않기 때문입니다. 그냥 잡아라.

확실히 방법이 있습니다. 먼저, 속도를 높이십시오 의존성 주입 그리고 비슷한 기술과 읽습니다 서비스 계층 그것이 당신이 여기서 필요한 것입니다.

서비스 계층에 관한 한, 어떤 종류의 구성 서비스가 필요하며, 이는 응용 프로그램의 일부가 구성 정보 (연결 문자열, URI 등)에 대한 쿼리를위한 모듈이 될 것입니다.

interface IConfigurationService
    string ConnectionString
    bool IntegratedSecurity
    bool EncryptProfiles

인스턴스가 하나만 있다는 것은 매우 간단해야합니다. IConfigurationService 시스템에서는 싱글 톤 패턴이 아닌 DI 컨테이너로 달성됩니다.

다음으로, 모든 DAL 서비스는 IConfigurationService:

class FooDal : IFooDal
    IConfigurationService ConfigurationService

그들이 지금 사용할 수 있도록 IConfigurationService.ConnectionString 연결 문자열을 잡습니다.

때에 따라 다르지.

싱글 톤 :

  • 클래스의 정확히 하나의 인스턴스가 존재하고
  • 글로벌 액세스를 제공합니다

글로벌은 글로벌 액세스 만 제공하지만 인스턴스화 수에 대해 보장하지 않습니다.

물론 마지막 옵션은 로컬 변수를 사용하는 것입니다. 즉, AA 매개 변수로 구성 정보를 생성자 또는 필요한 곳에 전달하십시오.

처음 두 가지 중에서 선택하는 것은 다소 쉬워야합니다. 클래스의 두 사례가 존재한다면 재앙입니까? 나는 아마 말하지 않을 것입니다. 앱의 하나의 특정 구성 요소에 별도의 옵션을 제공하거나 단위 테스트를 초기화하기 위해 자체 구성 클래스를 인스턴스화 할 수 있습니다.

당신이 어디에 있는지는 거의 없습니다 필요 정확히 하나의 인스턴스가 존재한다는 것을 보장합니다. 이러한 이유로, 글로벌은 싱글 톤보다 더 나은 선택 일 수 있습니다.

지역과 글로벌의 선택은 까다 롭습니다. 글로벌 돌연변이 상태는 일반적으로 피하는 것이 가장 좋습니다. 불변 상태는 문제가되지 않으며 글로벌 Mutable State와 동일한 동기화/동시성/확장 성 문제로 이어지지 않습니다.

그러나 종종 필요한 구성 요소로 전달하는 로컬 변수로 사용하는 것이 바람직 할 수 있습니다. 이 작업은 수동으로 수행 할 수 있습니다. 단순히 DB 액세스가 필요한 객체의 생성자로 전달하거나 어느 정도 IOC 컨테이너로 자동화 될 수 있습니다.

그러나 어쨌든 전역이 아닌 경우 코드가 더 일반적이고 휴대 성이됩니다. 클래스 및 글로벌 데이터에 대한 의존성이 숨겨진 경우 ~ 해야 하다 코드가 작동하기 위해 존재하면 다른 프로젝트에서 쉽게 사용할 수 없거나 전체 코드베이스를 너무 많이 리팩터링 할 수 없습니다.

일부 외부 데이터가 테스트에서 벗어나고 싶지 않다면 코드가 컴파일되지 않기 때문에 다시 테스트하기가 어려워집니다.

@anton이 말했듯이, 당신은 다음과 같은 것을 노출시키는 인터페이스가 있어야합니다.

interface IConfigurationService
    string ConnectionString

그런 다음 클래스 중 하나에 연결 문자열이 필요할 때마다 유효한 문자열이 포함 된 구성시 ICONFIGURATIONSERVICE 구현을 제공합니다. 앱이 시작될 때 구현을 만들 수있는 유효한 장소를 찾아야합니다 (아마도 데이터베이스 주소를 얻는 시간).

싱글 톤이나 글로벌에 비해 많은 작업이 보일지 모르지만 코드의 커플 링을 낮추어 재사용 가능성을 향상시키고 단위 테스트가 더 쉬워지고 일단 글로벌이 (대부분) 악이라는 것을 확신하면 매우 간단합니다 :)

이전에 언급 한 바와 같이,이를 위해 프레임 워크를 제공하는 IOC 컨테이너가 있지만, 귀하의 경우에는 과잉 일 수 있으며 "매직 박스"로 작업하기 전에 자신의 패턴을 사용하는 것이 좋을 수 있습니다.

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