鉴于此代码:
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。 怎么能实现呢?
答案 0 :(得分:3)
服务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));
}
}
答案 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;的文件)