[英]How to initialize class before it is needed in the Main method using 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注冊。 如何做到這一點?
服務IMessageProvider
和組件MessageProvider
在InstanceFactory
上的注冊不是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));
}
}
考慮使用一些Inversion of Control庫。 像Unity(但可能會過大)或SimpleContainer。
然后,您將在應用啟動時“注冊”接口實例(在示例中,您應具有“ bootstrapper.cs”之類的文件)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.