【问题标题】:Non-Lazy Static Initialization Block in C#C# 中的非惰性静态初始化块
【发布时间】:2010-12-21 04:46:07
【问题描述】:

我需要运行一些代码来为工厂模式注册一个类型。我会在 Java 中使用静态初始化块或在 C++ 中使用静态构造函数。

你如何在 C# 中做到这一点?该静态构造函数会延迟运行,并且由于该类型永远不会在代码中被引用,因此永远不会被注册。

编辑:我尝试了测试以查看注册码是否有效。但这似乎不起作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

[assembly: AssemblyTest.RegisterToFactory("hello, world!")]

namespace AssemblyTest
{
    [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)]
    sealed class RegisterToFactoryAttribute : Attribute
    {
        public RegisterToFactoryAttribute(string name)
        {
            Console.WriteLine("Registered {0}", name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

什么都没有打印出来。

【问题讨论】:

    标签: c# static initialization


    【解决方案1】:

    assembly level attribute 的构造函数中怎么样?

    示例:

    [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)]
    sealed class RegisterToFactoryAttribute : Attribute
    {
        public Type TypeToRegister { get; set; }
    
        public RegisterToFactoryAttribute(Type typeToRegister)
        {
            TypeToRegister = typeToRegister;
    
            // Registration code
        }
    }
    

    用法:

    [assembly:RegisterToFactory(typeof(MyClass))]
    

    --编辑装配级属性--

    经过一番研究,我认为它只会在查询时加载程序集属性:

    示例:

    object[] attributes =
        Assembly.GetExecutingAssembly().GetCustomAttributes(
            typeof(RegisterToFactoryAttribute), false);
    

    object[] attributes =
        Assembly.GetExecutingAssembly().GetCustomAttributes(false);
    

    不知道为什么,但是把这段代码@程序加载应该这样做。

    --编辑--

    我差点忘了:

    您是否考虑过使用MEF??这是解决这个问题的好方法。

    示例:

    class MyFactory
    {
        [ImportMany("MyFactoryExport")]
        public List<Object> Registrations { get; set; }
    
        public MyFactory()
        {
            AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
            CompositionContainer container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }
    
    [Export("MyFactoryExport")]
    class MyClass1
    { }
    
    [Export("MyFactoryExport")]
    class MyClass2
    { }
    
    [Export("MyFactoryExport")]
    class MyClass3
    { }
    

    【讨论】:

    • "'assembly' 不是此声明的有效属性位置。此声明的有效属性位置是 'type'。此块中的所有属性都将被忽略。"这是什么意思?
    • [assembly:RegisterToFactory(typeof(MyClass))] 放入您项目中的Assembly.cs 或任何文件的顶部。
    • @Jonathan 你把 [assembly:derpaherpattribute()] 放在命名空间声明中 namespace herp{[assembly:thisfails()]} 从命名空间范围中删除属性定义。
    • 好的,解决了。这段代码什么时候运行?我将其更改为接受一个字符串并让注册函数打印一些东西,但是当我运行程序集时没有打印。将代码放在第一篇文章中。
    • 在该代码中添加breakpoint。它应该在程序集加载时执行。
    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2019-11-13
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多