글쎄, Lazy가 인스턴스 속성을 사용하여 인스턴스에 인스턴스를 사용하여 속성을 제공한다면 어떻게 될까요? 우리가 클래스 내부에서 영리한 작업을하기 때문에이 필드는 여전히 비공개가 될 수 있으며, 실행 중에는 Singleton.Instance가 처음 참조 될 때까지 전체 필드가 여전히 게으르다. 그러나 코드가 Person 속성을 가져 오기 전에 개인 필드가 적절한 값을 가져야합니다. Singleton이 인스턴스를 생성 할 때 열심히로드되면 괜찮습니다.
C# In Depth에서 빌려온 여기에 싱글 톤을 참조하는 람다 (lambda)를 사용하여 초기화 된 완전한 게으른 Person 멤버가있는 유사 게으른 싱글 톤이 있습니다.
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
//I HIGHLY recommend you initialize _adusername,
//_adpassword and client here.
}
public static Singleton Instance
{
get
{
return instance;
}
}
private static readonly Lazy<IPersonManager> _person =
new Lazy<IPersonManager>(() => new PersonManager(Instance._adUserName, Instance._adPassword, Instance.client));
public static IPersonManager Person { get { return _person.Value; } }
private object _adUserName;
private object _adPassword;
private object client;
}
public class PersonManager:IPersonManager {}
public interface IPersonManager{}
편집 : 당신은 IOC의가있는 경우는 IOC의를 사용합니다. 현재 패턴을 혼합하려고합니다. 당신은 런타임 규칙을 사용하여 인스턴스 클래스를 싱글 톤으로 "승격"하기 위해 IoC를 사용하지만이 인위적인 싱글 톤의 인스턴스 스코프 된 데이터 필드를 기반으로 컴파일러가 적용한 지연된 정적 속성을 인스턴스화하려고합니다. 이것은 단순히 작동하지 않을 것입니다.
일단 IoC를 실행하면 모든 종속성을 등록하고 주입해야합니다. PersonManager에 Ninject를 IPersonManager 구현으로 등록한 다음 IPersonManager를 생성하는 Func을 제공 할 수있는 기본 Singleton DataAdapter에 대한 생성자를 만듭니다.일반적으로이 목적을 위해 사용자 지정 함수를 정의 할 수 있습니다.이 경우 IoC를 사용하여 컨테이너에 보관 된 단일 DataAdapter 인스턴스에서 필요한 인스턴스 데이터를 제공합니다.
경고 : 심각하게 추악한 반사를 피하기 위해 데이터 필드를 공개적으로 읽을 수 있어야합니다. 필드를 읽기 전용 필드 또는 get 전용 속성으로 정의하여 사람들이 변경하지 못하게하지만 소비자가 볼 수있게 할 수 있습니다.
편집 2 :가 여기에 내가 생각했던 내용은 다음과 같습니다
//in your Ninject bindings:
kernel.Bind<DataAdapter>().ToSelf().InSingletonScope();
kernel.Bind<PersonManager>().ToSelf().InSingletonScope();
//to bind the interface
kernel.Bind<IPersonManager>()
.ToMethod(c =>{
var adapter = kernel.Get<DataAdapter>();
//this is why these fields would have to be public
var arg1 = new ConstructorArgument("adUserName", adapter._adUserName)
var arg2 = new ConstructorArgument("adPassword", adapter._adPassword)
var arg3 = new ConstructorArgument("client", adapter.client)
//the names of the arguments must match PersonManager's constructor
c.Kernel.Get<PersonManager>(arg1, arg2, arg3);
});
//now in your DataAdapter, specify a constructor like this, and Ninject will provide:
public DataAdapter(Func<IPersonManager> personFunc)
{
//_person should obviously not be instantiated where it's defined in this case
_person = new Lazy<IPersonManager>(personFunc);
}
당신은 값을 갖는, 그들은 개체의 생성자 내에서 값을 할당하고하지 개체에 대한 잘못된입니다. null 참조 예외가 발생하지 않고 해당 필드를 찾을 수 없기 때문에 컴파일 오류가 발생합니다. 내가 제안한 내 (작업) 이중 확인 잠금 솔루션보다 당신이 무엇을 제안하고 있는지 잘 모르겠습니다. – Arbiter
@Arbiter 코드에서 초기화하는 것이 명확하지 않습니다. KeithS는 당신을 위해 일해야한다고 제안합니다. 나는 패턴을 섞지 말라고 제안했다. – sarvesh