【问题标题】:How to create a lazy singleton aspect with PostSharp?如何使用 PostSharp 创建一个惰性单例方面?
【发布时间】:2018-08-21 19:17:59
【问题描述】:

假设具有私有构造函数的密封类的以下单例声明:

private static readonly Lazy<MyClass> _singleton = new Lazy<MyClass>(() => new MyClass());
public static MyClass Instance => _singleton.Value;

有没有办法创建一个 PostSharp 方面,允许我向 Instance 属性添加一个属性 (PsSingleton):

[PsSingleton]
public static MyClass Instance {get; set;}

让这个类在运行时变成一个惰性单例?

【问题讨论】:

    标签: c# singleton postsharp aspect


    【解决方案1】:
    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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多