I need to run some code to register a type for a factory pattern. I would do this in Java with a static initialization block or in C++ with a static constructor.
How do you do this in C#? That static constructor gets run lazily and since the type will never be referred to in the code, never gets registered.
EDIT: I tried a test to see the registration code work. This doesn't seem to be working though.
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)
        {
        }
    }
}
Nothing gets printed.
How about in a constructor for an 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
    }
}
Usage:
[assembly:RegisterToFactory(typeof(MyClass))]
After doing some research, I figured it will only load the assembly attributes if they are queried:
object[] attributes =
    Assembly.GetExecutingAssembly().GetCustomAttributes(
        typeof(RegisterToFactoryAttribute), false);
or
object[] attributes =
    Assembly.GetExecutingAssembly().GetCustomAttributes(false);
Don't know why but putting this code @ the program load should do it.
--EDIT--
I almost forgot:
Have you considered using MEF?? It's a great solution to this problem.
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
{ }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With