| 작가 | |
|---|---|
| 웹 사이트 | https://github.com/lsauer/csharp-singleton |
| 특허 | MIT 라이센스 |
| 현재의 | |
| 패키지 | PM> Install-Package CSharp.Portable-Singleton |
| 설명 | 단일 인스턴스를 시행하고 관리하기 위해 일반적이고 휴대용, 문서화 및 사용하기 쉬운 싱글 톤 패턴 구현 |
| 선적 서류 비치 | 완전한 참조 v2.0.0.4 |
| 서명 |
|
| 정식 버전 | 너겟 | 짓다 | Nuget 설치 |
|---|---|---|---|
| csharp.portable-singleton | PM> Install-Package CSharp.Portable-Singleton |
사회의:
Nuget 패키지에도 포함 된 전체 참조를 보려면 여기를 방문하십시오.
PM> Install-Package CSharp.Portable-Singleton 과 함께 패키지를 설치하십시오.using Core.Singleton; .MySingleton : Singleton<MySingleton> 으로 높이십시오.아래 예를 찾으십시오. 실제로 코드가 어떻게 보일지 엿볼 수 있습니다.
using Core . Singleton ;
public class AClass : Singleton < AClass >
{
// a public parameterless constructor is required
public AClass ( ) { }
public AMethod ( ) { Console . Write ( " Write called " ) ; }
}
AClass . CurrentInstance . AMethod ( ) ;
System . Diagnostics . Debug . Assert ( ReferenceEquals ( new AClass ( ) , AClass . CurrentInstance ,
" Same Instance " ) ;.NET은 특히 소프트웨어 설계 패턴을 시행하지 않습니다. 싱글 톤 패턴은 소프트웨어에서 창조적 디자인 패턴 으로 주목할만한 것이며, 여기서 객체의 하나의 인스턴스 만 인스턴스턴스 될 수 있으므로 일반적으로 단일 액의 유용성을 단일 액세스 리소스의 생성 또는 포장으로 확장합니다.
새로운 싱글 톤을 만드는 것은 간단 Singleton<> .
와 같은:
internal class MyClass : Singleton < MyClass > {
.. .
}싱글 톤의 사용 예는 .NET 콘솔 응용 프로그램을위한 개선 된 콘솔 래퍼이며, 다른 일반적인 시나리오는 성능과 동기화 측면을 제공하는 곳입니다.
참고 : 현대 플랫폼에서 실행되는 대규모 응용 프로그램은 특히 설계 패턴의 프레임 워크 지원을 통해 싱글 톤보다 개선 된 솔루션에 의지 할 수 있습니다.
시작하려면 다음 구문을 준수하는 것이 좋습니다.
namespace MyNamespace {
using Core . Singleton ;
public class MyClass : Singleton < MyClass > { } ;
var somePropertyValue = Singleton < MyClass > . CurrentInstance . SomeProperty ;
// ...and for a method:
var someMethodValue = Singleton < MyClass > . CurrentInstance . Add ( 1 , 2 ) ;
} 새로운 Singleton<T> 인스턴스를 초기화하는 몇 가지 다른 방법이 있으며, 여기서 T 사용자 지정 로직을 구현하는 클래스를 참조하여 각 논리적 싱글 톤 클래스의 유형입니다.
Singleton<T>.CurrentInstance 또는 Singleton<T>.Instancenew T()[Singleton]class T : Singleton<T>{...} 와 같은 SingletonAttribute 사용 및 Singletonmanager 인스턴스에서 Initialize() 호출Activator.CreateInstance(typeof(T)); 사용new T(...) 로 클래스 T를 InscatingSingletonManager 사용 (아래 참조)TypeInfo 확장 메소드를 사용하여 ToSingleton() EG typeof(MyClass).GetTypeInfo().ToSingleton()Examples 를 참조하십시오. 일반 Singleton<T> 작품에는 다음과 같은 정적 특성이 있으며,이 특성은 EnumSingletonProperty.cs 에 참조됩니다.
[ Description ( " The current or created instance of the singleton " ) ]
CurrentInstance = 1 << 1 ,
[ Description ( " The internally created instance of the singleton " ) ]
Instance = 1 << 2 ,
[ Description ( " Gets whether the singleton of type TClass is initialized " ) ]
Initialized = 1 << 3 ,
[ Description ( " Gets whether the singleton of type TClass is disposed " ) ]
Disposed = 1 << 4 ,
[ Description ( " Gets whether the singleton of type TClass is blocked for handling " ) ]
Blocked = 1 << 5 ,특별한 경우 처분이 도움이되거나 필요한 경우도 있습니다. 사례에 대한 예제를 참조하십시오.
myobj is ISingletontypeof(MyClass).GetTypeInfo().IsSingleton() 비교 유형이 이미 TypeInfo 인스턴스 인 경우 각각 위에 표시된대로 GetTypeInfo() 로 호출을 생략하십시오.
(Instance == null) 다음 속성은 INotifyPropertyChanged 의 협약을 따르지만이를 구현하지는 않습니다. 대조군 PropertyChangedEventHandler 대신 맞춤형 유형의 SingletonPropertyEventHandler 사용합니다.
싱글 톤 인스턴스 자체가 폐기되어 쓰레기 수집에 무료로 사용되는 경우에도 Disposed 및 Initialized 허용되도록 정적으로 구성된 이벤트 PropertyChanged 자체가 정적으로 선언됩니다.
public static event SingletonEventHandler PropertyChanged ; 또한 부동산 Manager 변경 될 때 이벤트가 트리거됩니다. 이 속성은 ISingletonManager 구현하는 SingletonManager 인스턴스의 Setter 종속성 주입에 사용됩니다.
주어진 프로젝트에서 여러 개의 싱글 톤 클래스의 경우 SingletonManager 인스턴스를 사용하고 전달하는 것이 좋습니다.
예를 들어, 청소 후 작업에 대한 Disposed 이벤트를 들으려면 응용 프로그램의 종료 또는 종료 중에 다음과 같이 유사한 코드 샘플을 사용할 수 있습니다.
Singleton < MyClass > . PropertyChanged += ( sender , arg ) => {
if ( arg . Property == SingletonProperty . Disposed ) {
.. .
}
.. .
} ;
//... prep the application until it is sensible to init the singleton
var logger = Singleton < RenderLogger > . GetInstance ( ) ; 싱글 톤은이 시점에서 초기화 될 필요조차 없으므로 싱글 톤 생성자 내에서 일반적인 IStream 요소를 자세히 설명하는 것이 안전합니다.
PropertyChanged 의 이벤트 핸들러는 ISingleton 의 인스턴스를 첫 번째 인수로 전달하고, 두 번째 매개 변수로서 SingletonPropertyEventArgs 의 인스턴스는 다음과 같은 속성을 포함합니다.
Name : 변경된 속성의 이름을 포함하는 문자열Value : 부동산의 상자 현재 값Property : SingletonProperty 의 열거 값으로 인코딩 된 속성 다음 코드 발췌문은 새로운 SingletonPropertyEventArgs 인스턴스를 만듭니다.
var propertyName = SingletonProperty . Instance . ToString ( ) ;
var propertyValue = 100 ;
var args = new SingletonPropertyEventArgs ( SingletonProperty . Initialized , propertyValue ) ; 다음 예는 런타임까지 알려지지 않은 싱글 톤 속성에 액세스하기 위해 이벤트 핸들러 내에서 GetValue 의 동적 사용을 보여줍니다.
Singelton < MyClass > . PropertyChanged += ( sender , arg ) =>
{
if ( arg . Property == SingletonProperty . Initialized )
{
var value = sender . GetValue ( " Value " ) ;
}
} ; 일반적으로 사용자 정의 인터페이스 (예 : ISingletonTemplate<TCommonDenominator> )를 통해 유사한 싱글 톤의 ACCS 속성에 권장되며 명시 적 캐스트와 함께 is 연산자를 사용하여 특정 타이 테크를 수행합니다.
Singelton < MyClass > . PropertyChanged += ( sender , arg ) =>
{
if ( arg . Property == SingletonProperty . Initialized )
{
if ( sender is MyClass /*check including inherited types*/ ) {
var senderTyped = sender as MyClass ;
senderTyped . SetDateTime ( DateTime . Now ) ;
} else if ( sender . GetType ( ) == typeof ( MyStrictClass ) /*check excluding inherited types*/ ) {
var senderTyped = sender as MyStrictClass ;
Console . WriteLine ( senderTyped . SayHello ( ) ) ;
} else {
return ;
}
// do something else if the type got matched
}
} ; 다음 예에서 클래스 AClass 'Singleton Business Logic'을 구현하고 Singleton<> 에서 상속됩니다.
어셈블리, 네임 스페이스 및 파생을 포함하는 것으로 충분합니다 : Singleton<AClass> 예상되는 테스트 된 동작을 얻으려면 :
using Core . Extensions .
public class AClass : Singleton < AClass >
{
public string AMethod ( [ CallerMemberName ] string caller = " " )
{
return caller ;
}
public static string AStaticMethod ( [ CallerMemberName ] string caller = " " )
{
return caller ;
}
}
static void Main ( string [ ] args )
{
Console . WriteLine ( " Running: " + typeof ( Program ) . Namespace + " . Press any key to quit... " ) ;
var aClass = new AClass ( ) ;
Console . WriteLine ( " Expected: 'Main'; Observed: '{0}' " , aClass . AMethod ( ) ) ;
Console . WriteLine ( " Expected: 'Main'; Observed: '{0}' " , AClass . CurrentInstance . AMethod ( ) ) ;
Console . WriteLine ( " Expected: 'Main'; Observed: '{0}' " , AClass . AStaticMethod ( ) ) ;
object bClass = null ;
try
{
bClass = new AClass ( ) ;
}
catch ( SingletonException exc )
{
if ( exc . Cause == SingletonCause . InstanceExists )
bClass = AClass . CurrentInstance ;
}
var condition = Object . ReferenceEquals ( aClass , bClass ) ;
//> true
var input = Console . ReadKey ( true ) ;
}참고 : 예제 폴더 내에서 더 많은 예제가 전체적으로 제공됩니다.
위 의이 예는 다음의 예상 결과를 산출합니다.
Running: Examples.Example1. Press any key to quit...
Expected: ' Main ' ; Observed: ' Main '
Expected: ' Main ' ; Observed: ' Main '
Expected: ' Main ' ; Observed: ' Main ' 싱글 톤 클래스는 SingletonException 던질 수 있습니다 (그림 1 참조).
이것들은 EnumSingletonCause.cs 에서 참조됩니다.
[ Description ( " Indicates the default or unspecified value " ) ]
Unknown = 1 << 0 ,
[ Description ( " Indicates an existing Singleton instance of the singleton class `T` " ) ]
InstanceExists = 1 << 1 ,
[ Description ( " Indicates that the created Singleton instance does not have a parent class " ) ]
NoInheritance = 1 << 2 ,
[ Description ( " Indicates that an exception by another class or module was caught " ) ]
InternalException = 1 << 3 ,
[ Description ( " Indicates that the Singleton must not be instanced lazily through an Acccessor, but the instance explcitely declared in the source-code " ) ]
NoCreateInternal = 1 << 4 ,
[ Description ( " Indicates that the Singleton must not be disposed " ) ]
NoDispose = 1 << 5 ,
[ Description ( " Indicates an existing mismatch between the singleton class `T` and the logical singleton class or parent-class invoking the constructor " ) ]
InstanceExistsMismatch = 1 << 6 , 글로벌 초기화와 수축의 경우 싱글 톤의 목적을 위해서는 논리적 싱글 톤 클래스는 다음 코드 예제에 표시된 것처럼 항상 [Singleton] 에 기인해야합니다.
[ Singleton ( disposable : false , initByAttribute : false , createInternal : true ) ]
public class AClass : Singleton < AClas > {
.. .
}속성에는 세 가지 액세스 가능한 속성이 있습니다.
Disposable (default = false) : 폐기 할 수있는 경우 true 로 설정CreateInternal (default = true) : 싱글 톤이 사용자 소스 코드 내에서 명시 적 선언에 의해 외부에서만 인스턴스화되어야하는 경우 false 로 설정InitByAttribute (default = true) : SingletonManager 메소드에 의한 공동 초기화를 Initialize 하도록 true 로 설정 대규모 응용 프로그램의 여러 싱글 톤 유형 및 인스턴스를 관리하려면 SingletonManager 클래스를 다음과 같이 사용하십시오.
다음 예는 싱글 톤 Pool 반복하고 싱글 톤 유형에 따라 논리를 수행합니다.
var singletonTypes = new List<Type>() { typeof(ParentOfParentOfAClass), typeof(ParentOfAClass), typeof(IndispensibleClass) };
// create the singletons and add them to the manager
var singletonManager = new SingletonManager(singletonTypes);
foreach (var singleton in singletonManager.Pool)
{
if (singleton.Value is ParentOfParentOfAClass)
{
var instanceTyped = singleton.Value as ParentOfParentOfAClass;
Console.WriteLine($"POPOAClass ImplementsLogic: {instanceTyped.ImplementsLogic}");
} else {
Console.WriteLine(singleton.Value.GetType().FullName);
}
}
singletonManager.Pool 속성은 친숙한 LINQ 구문에서 쿼리를 작성할 수있는 스레드-안전, ConcurrentDictionary<Type, ISingleton> 인스턴스에 대한 액세스를 제공합니다.
배치 된 싱글 톤은 결코 삭제되지 않지만 SingletonManager의 AddOrUpdate 방법을 사용하여 null 로 설정됩니다.
알려진 유형의 새로운 인스턴스를 만들려면 다음과 같이 일반적인 CreateInstance 메소드를 사용하십시오.
var singletonManager = new SingletonManager ( ) ;
var gameStatics = singletonManager . CreateSingleton < GameStatics > ( ) ;유형이 런타임에만 알려져 있거나 사용 가능한 경우 다음 코드 예제와 같이 유형을 인수로 동적으로 전달하는 경우.
var singletonManager = new SingletonManager ( ) ;
var getInstance = ( type ) => {
var gameStatics = singletonManager . CreateSingleton ( type ) ;
} ;
getInstance ( typeof ( GameStatics ) ) ;싱글 톤 클래스 자체에는 시리얼 라이저의 구현을 방해하는 것이 없지만 테스트뿐만 아니라 구현은 개발자의 손에 달려 있습니다.
일반 솔루션은 권장되지 않고 필요한 경우 해당 싱글 톤의 구현 된 구현을 권장합니다. 예를 들어 최대 절전 모드 / 이력서 상태 시나리오에서. 그 목적으로 SingletonManager를 확장하는 것이 좋습니다.
또한이 토론을 살펴보십시오
이 라이브러리는 Xunit 테스트 프레임 워크에 의해 테스트되었습니다. 테스트는 여러 클래스로 실행되며, AClass 중 하나는 간단한 대포 상속 스키마에 부착됩니다.
그림 1 : : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 1 : 그림 및 그림 1 : 그림 및 그림 및 그림 1 : 그림 및 그림 1 : 그림 및 그림 및 그림 1 : 그림 및 그림 및 그림 1 : 그림 및 그림 주 및 그림 주 및 그림은 나타내 나타내는 나타내는 나타내는 나타내는 나타내 나타내는 그림들이 나타내 나타내 한 나타내 나타내 나타내는 나타내 나타내 나타내 나타내 나타내 나타내 나타내 나타내 나타내 나타내 나타내 나타내OOO언 나타내 나타내 나타내 나타내 나타내 :
버그에 부딪쳤다 고 확신한다면 새로운 문제를 여기에서 밀어 넣으십시오.
서로 계층 적으로 서로를 물려받는 여러 클래스의 중첩 된 상속 시나리오와 싱글 톤에서 파생 된 결정된 기본 클래스에서 논리적 싱글 톤 클래스를 정의하는 것이 중요합니다. 이것은 단일 책임을 따른 SingleOTN의 논리를 구현하기위한 클래스입니다.
또한 기본 클래스의 일반 유형 T 결정하는 클래스 - Singleton<T> 자체의 클래스는 Singleton<T> 상속해야합니다.
보다 복잡한 상속 싱글 톤 시나리오는 README_Example_Advanced.md 를 참조하십시오.
이 라이브러리를 사용할 때 좋은 가독성을 유지하려면 :
singleton<T> AClass.Instance 일반 매개 변수로 전달 된 것보다 다른 유형에서 정적 액세서 액세스를 피하십시오 ParentOfParentOfAClass.InstanceSingletonAttribute 사용하여 싱글 톤의 목적에 따라 싱글 톤 클래스에 속합니다.