0

종속성 주입을 사용하는 방법을 배우려하고 있지만 데이터베이스에 문제가 있습니다. 이것은 지금까지의 프로세스입니다.종속성 주입을 사용하여 데이터베이스에 연결

저는 컨트롤러가 내 클래스 라이브러리와 다른 리포지토리를 사용하는 MVC 프로젝트를 가지고 있습니다. 모든 리포지토리에서 동일한 데이터베이스가 사용됩니다.

는 처음에 나는 저장소 위해 Application_Start 방법 등록 SimpleInjector을 사용 :

var container = new Container(); 
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); 
var client = new GraphClient(uri, username, password); 
container.Register<IRepoA>(() => new RepoA(client); 
container.Register<IRepoB>(() => new RepoB(client); 
container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 
container.Verify(); 

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 

을 그리고 모든 방법으로,이 같은 짓 :

client.Connect(); 
    client.performSomeQuery(); 
    client.Dispose(); 

이 작동하지만 나는 것을 의미한다 메소드를 호출 할 때마다 데이터베이스에 다시 연결하십시오.

var container = new Container(); 
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); 
var client = new GraphClient(uri, username, password); 
client.Connect(); 
container.Register<IRepoA>(() => new RepoA(client); 
container.Register<IRepoB>(() => new RepoB(client); 
container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 
container.Verify(); 

을하지만 난 결코 내 연결을 배치하지 얻을 : 이것을을 방지하기 위해 여기에 연결 통화를 이동했다.

나는 이제 내 databaseclient를 등록하는 것으로 생각했다;

container.RegisterSingleton(() => 
{ 
    var client = new GraphClient(uri, username, password); 
    client.Connect(); 
    return client; 
}); 

그리고 이런 식으로 주입 :

container.Register<IRepoA>(() => new RepoA(container.GetInstance<GraphClient>())); 

이 그것을 할 수있는 올바른 방법이 있나요?

컨테이너 수명이 끝날 때 연결이 끊어 질 것이라고 정확하게 이해하고 있습니까?

클라이언트를 등록 할 때 "암시 적으로 캡처 된 클로저 : 컨테이너"가 나타납니다. 여기

+0

요청 당 새 연결을 만드는 것이 일반적인 방법입니다. 생각해보십시오. 웹 응용 프로그램은 수십 또는 수백 개의 요청을 동시에 처리해야 할 수도 있습니다. 이 모든 것들이 동일한 실제 연결 객체에 대해 경쟁하는 것을 원하지는 않습니다. – GPW

+0

방금 ​​읽었을 때 @GPW를 호출하는 데 비용이 많이들 것이라고 생각했습니다. "대화 할 각 데이터베이스에 대해 하나의 인스턴스 만 가져야합니다 (일반적으로 하나) 이렇게하면 연결에 대한 초과 호출이 발생하지 않습니다) 방법 "neo4j 서버에 왕복이 필요합니다." [링크] (https://github.com/Readify/Neo4jClient/wiki/connecting) 각 메소드에서 connect를 호출하면 충분합니까? 또는 각 메서드마다 새 클라이언트 객체를 만들어야합니까? (var client = new GraphClient (_uri, _username, _password)) { client.Connect(); client.Query(); client.Dispose(); } – lst

+0

제가 알기 론, 당신이 쓰레드 안전하고 싱글 톤 접근법을 제안하는 특정 라이브러리를 사용하고 있다는 것을 깨닫지 못했습니다. Lambdas에 수업을 등록하는 이유가 있습니까? DI를 사용하여 클래스와 구현을 등록하기 만하면됩니다. 실제로 IRepoA를 만드는 방법을 지정할 필요가 없으므로 종결 경고를 피할 수 있습니다. – GPW

답변

1
그래서 때로는 잘못된 경로에 당신을 얻을 수있는 올바른 방법을 묻는

일을하는 하나 개 이상의 방법이 ... ...

을하지만, 내가 귀하의 경우 할 거라고 것입니다 .. .

내가 작업 단위라는 패턴을 소개합니다 ...

당신은 당신이 가능하게 모든 일을 내 다양한 ​​DB의 상호 작용을 수행하는 작업과 수명 내에서 단위를 열 비즈니스 트랜잭션으로 생각 것

데이터베이스 트랜잭션. 이러한 모든 상호 작용은 서로 다른 리포지토리에 퍼질 수 있습니다. 롤백이 필요한 오류없이 전체 일괄 처리 작업이 완료되면 작업 단위가 완료되었다고 선언하고 범위 (사용 범위 (...) 범위 그대로)를 지정합니다.

오류가있는 경우 완전한 경우 사실에 따라 수명이 종료되기 전에 작업하여 장치의 수명의 끝에 ...이 완료

를 선언하지 않는, 당신은 커밋 할 수 있습니다 또는 (일반적으로 그것은 단지 하나) 다시 모든 기저의 DB 트랜잭션을 롤 선언되었거나 안된다

이 작업 단위 오브젝트는 대개 내 db 연결 오브젝트도 보유하고 리포지토리에 대한 연결을 제공합니다.

의존성 주입으로 다시 인스턴스화하는 동안 저장소가 요청하는 인터페이스를 기반으로 다른 DB 연결을 제공하는 팩토리 메소드를 가질 수 있습니다.

일반적으로 연결이 필요한 첫 번째 저장소는 공장이 하나의 저장소를 만들고 열어줍니다 (사용 된 repos를 기반으로 다른 연결을 가질 수 있음). 연결을 요청하는 두 번째 저장소는 생성 된 연결을 가져옵니다 전에 열기 ...

작업 단위의 끝 (IDisposable 참조)은 연결의 끝을 의미합니다. ... 연결의 끝은 열린 연결과 repos의 끝을 의미합니다 ... 나중에 인스턴스화되기 때문에 using 블록을 사용하고 사용 된 리소스에 따라 해당 블록을 벗어나지 않아야합니다.