DI 및 IoC 컨테이너로 시작하는 사람들에게 흔히있는 실수입니다. 범위의 일관성을 유지해야합니다. 은 의존성이있는 서비스가 싱글 톤 범위에 바인딩 될 때 요청 범위에 종속 된 종속성을 가질 수 없습니다 (또는 더 나쁜 것은 컨테이너가 전혀 관리하지 않는 일부 범위를 가짐). 그것은 단순히 잘못된 것입니다.
당신은 여기에 두 가지 기본 옵션이 있습니다
바인드 멤버 자격 공급자 자체와 함께 InSingletonScope
로 CustomerService
을. 분명히 이것은 장수명의 EF 서비스의 모든 일반적인 단점을 가지고 있습니다.
회원 공급자가 CustomerService
인스턴스에 의존하지 않도록하십시오. 대신 을 만들 수있는 CustomerServiceFactory
에 종속성을 만들고CustomerService
인스턴스를 만들고 구성원 공급자에 대한 모든 호출을 일시적으로 처리하십시오. # 2의
는 만들고 공장을 결합하는 과정은 매우 간단합니다 : 당신의 모듈에 다음
public interface ICustomerServiceFactory
{
ICustomerService GetService();
}
public class NinjectCustomerServiceFactory : ICustomerServiceFactory
{
private readonly IKernel kernel;
public NinjectCustomerServiceFactory(IKernel kernel)
{
if (kernel == null)
throw new ArgumentNullException("kernel");
this.kernel = kernel;
}
public ICustomerService GetService()
{
return kernel.Get<ICustomerService>();
}
}
:
Bind<ICustomerService>()
.To<EFCustomerService>();
.InRequestScope();
Bind<ICustomerServiceFactory>()
.To<NinjectCustomerServiceFactory>()
.InSingletonScope();
참고 범위 여기. 서비스 자체는 여전히 요청 범위이지만 팩토리는 공급자와 동일한 범위 인 싱글 톤입니다. 이것은 팩토리가 싱글 톤 (더 많거나 적음) 인 커널에 직접 연결되기 때문에 가능합니다.
당신은 너무처럼 보이는 회원 코드로 끝날 것 :
public class MyMembershipProvider : MembershipProvider
{
public override MembershipUserCollection GetAllUsers()
{
var service = serviceFactory.GetService();
var serviceUsers = service.GetAllUsers();
return serviceUsers.Select(u => CreateMembershipUser(u));
}
// Other methods...
[Inject]
public ICustomerServiceFactory ServiceFactory { get; set; }
}
서비스 자체는 여전히 요청 범위의 것이기 때문에 이것은 실제로 매우 잘 작동
하지만 공장 (및 멤버 자격 공급자)를합니다 각 요청 중에 다른 인스턴스를 가져와야합니다. 뿐만 아니라 멤버쉽 공급자는 단일 요청 중에 얼마나 많은 멤버십 메소드가 호출되는지에 관계없이 과 동일한 인스턴스 (공장을 통해)를 얻을 수 있습니다. 따라서 레거시 코드에 통합해야 함에도 불구하고 DI의 거의 모든 이점을 얻게됩니다.
느낌이 바보 같아서, ninject가 Memebership 공급자에게 속성을 주입하지 않는 문제를 탐색하는 동안 질문을 읽지도 않았고, 다른 문제의이 솔루션을 구현했습니다. 물론, 아직 주입되지 않았습니다. 재산. 그리고 멤버쉽 제공 업체에서 생성자의 상처를 사용할 수 없습니다 ... –