如何使用 PostSharp 创建惰性单例方面?
How to create a lazy singleton aspect with PostSharp?
假设密封 class 具有私有构造函数的以下单例声明:
private static readonly Lazy<MyClass> _singleton = new Lazy<MyClass>(() => new MyClass());
public static MyClass Instance => _singleton.Value;
有没有一种方法可以创建 PostSharp 方面,允许我将属性 (PsSingleton) 添加到 Instance
属性 中:
[PsSingleton]
public static MyClass Instance {get; set;}
并让 class 在 运行 时变成懒惰的单身人士?
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
using System;
using System.Reflection;
namespace LazySingletonSample
{
class Program
{
static void Main(string[] args)
{
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
}
}
public class TestClass
{
[LazySingleton]
public static TestClass Instance;
public void SayHello()
{
Console.WriteLine("Hello from singleton!");
}
}
// TODO: Restrict usage
[PSerializable]
public sealed class LazySingletonAttribute : LocationInterceptionAspect
{
object singletonInstance;
ConstructorInfo constructor;
public override bool CompileTimeValidate(LocationInfo locationInfo)
{
// TODO: check that:
// - field name is "Instance"
// - field type is the same as the declaring type
// - there is only a default constructor
// - the constructor is private
// - the constructor is not called anywhere
// - the field is not set anywhere
return true;
}
public override void CompileTimeInitialize(LocationInfo targetLocation, AspectInfo aspectInfo)
{
this.constructor = targetLocation.DeclaringType.GetConstructor(new Type[] { });
}
public override void OnGetValue(LocationInterceptionArgs args)
{
if (this.singletonInstance == null)
{
Console.WriteLine("Creating singleton instance.");
this.singletonInstance = constructor.Invoke(new object[] { });
}
Console.WriteLine("Returning singleton instance.");
args.Value = this.singletonInstance;
}
public override void OnSetValue(LocationInterceptionArgs args)
{
throw new InvalidOperationException();
}
}
}
假设密封 class 具有私有构造函数的以下单例声明:
private static readonly Lazy<MyClass> _singleton = new Lazy<MyClass>(() => new MyClass());
public static MyClass Instance => _singleton.Value;
有没有一种方法可以创建 PostSharp 方面,允许我将属性 (PsSingleton) 添加到 Instance
属性 中:
[PsSingleton]
public static MyClass Instance {get; set;}
并让 class 在 运行 时变成懒惰的单身人士?
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
using System;
using System.Reflection;
namespace LazySingletonSample
{
class Program
{
static void Main(string[] args)
{
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
}
}
public class TestClass
{
[LazySingleton]
public static TestClass Instance;
public void SayHello()
{
Console.WriteLine("Hello from singleton!");
}
}
// TODO: Restrict usage
[PSerializable]
public sealed class LazySingletonAttribute : LocationInterceptionAspect
{
object singletonInstance;
ConstructorInfo constructor;
public override bool CompileTimeValidate(LocationInfo locationInfo)
{
// TODO: check that:
// - field name is "Instance"
// - field type is the same as the declaring type
// - there is only a default constructor
// - the constructor is private
// - the constructor is not called anywhere
// - the field is not set anywhere
return true;
}
public override void CompileTimeInitialize(LocationInfo targetLocation, AspectInfo aspectInfo)
{
this.constructor = targetLocation.DeclaringType.GetConstructor(new Type[] { });
}
public override void OnGetValue(LocationInterceptionArgs args)
{
if (this.singletonInstance == null)
{
Console.WriteLine("Creating singleton instance.");
this.singletonInstance = constructor.Invoke(new object[] { });
}
Console.WriteLine("Returning singleton instance.");
args.Value = this.singletonInstance;
}
public override void OnSetValue(LocationInterceptionArgs args)
{
throw new InvalidOperationException();
}
}
}