如何在使用C#的Main方法中初始化类之前

时间:2014-09-21 23:52:54

标签: c#

鉴于此代码:

using System;
using System.Collections.Generic;
using FactoryCallback = System.Func<System.Object>;

interface IMessageProvider
{
    string Message { get; }
}

class MessageProvider : IMessageProvider
{
    private Random generator = new Random();

    public static void Register()
    {
        InstanceFactory.Register(typeof(IMessageProvider), () => new MessageProvider());
    }

    public string Message
    {
        get
        {
            switch (generator.Next(3))
            {
                case 0:
                    return "No matter where you go, there you are.";
                case 1:
                    return "Once I thought I'd made a mistake, but I was wrong.";
                case 2:
                    return "I used to think I was indecisive; now I'm not so sure";
                default:
                    throw new IndexOutOfRangeException();
            }
        }
    }
}

class InstanceFactory
{
    private static Dictionary<Type, FactoryCallback> typeCallbacks =
        new Dictionary<Type, FactoryCallback>();

    public static void Register(Type type, FactoryCallback callback)
    {
        typeCallbacks.Add(type, callback);
    }

    public static Object InstanceOf(Type type)
    {
        return typeCallbacks[type]();
    }
}

public class RandomMessage
{
    public static void Main()
    {
        IMessageProvider provider =
            InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider;
        Console.WriteLine(String.Format("The message is:\n{0}", provider.Message));
    }
}

此程序无法成功运行,因为MessageProvider实际上从未实际注册InstanceFactory。 显然,可以将对MessageProvider.Register的调用添加到RandomMessage.Main的开头。但是,现在要求RandomMessage具有MessageProvider的知识并且无法实现InstanceFactory类的整个目的,该类旨在分离如何根据某些内容创建内容。 我希望MessageProvider能够在RandomMessage.Main尝试创建IMessageProvider实例之前自动注册InstanceFactory。 怎么能实现呢?

3 个答案:

答案 0 :(得分:3)

服务IMessageProvider和组件MessageProviderInstanceFactory的注册不是MessageProvider实施的责任,它是应用程序的基础架构问题,因此应该是在Main方法内部完成。

public class RandomMessage
{
    public static void Main()
    {
        // Register services with InstanceFactory at the start of Main method
        InstanceFactory.Register(typeof(IMessageProvider), () => new MessageProvider());

        IMessageProvider provider = InstanceFactory.InstanceOf(typeof(IMessageProvider)) as IMessageProvider;
        Console.WriteLine(String.Format("The message is:\n{0}", provider.Message));
    }
}

答案 1 :(得分:0)

如果您在致电MessageProvider之前以某种方式引用InstanceFactory.InstanceOf(),则可以向MessageProvider类添加static constructor

static MessageProvider()
{
    Register();
}

如果它不是一个选项,你可以通过反射方式为你想要注册的所有类添加custom attribute并在{的静态构造函数中为所有类调用Register()。 {1}}就像描述here

一样

答案 2 :(得分:0)

考虑使用一些Inversion of Control库。像Unity(但它可能是矫枉过正)或SimpleContainer。

然后你会注册&#39;您的应用程序启动时的界面实例(在示例中,您应该拥有类似&#39; bootstrapper.cs&#39;的文件)