gpt4 book ai didi

c#-4.0 - 在此示例中,IClock 如何使用 SystemClock 解析?

转载 作者:行者123 更新时间:2023-12-01 12:42:54 24 4
gpt4 key购买 nike

我想通过这个截屏视频学习 IOC 原理 Inversion of Control from First Principles - Top Gear Style

我尝试按照截屏视频进行操作,但在 AutomaticFactory 尝试创建 AutoCue 对象时出现错误。 AutoCue 类具有采用 IClock 而不是 SystemClock 的构造函数。但我的问题是,在截屏视频中,IClockAutomaticFactory 中用 SystemClock 解决了。但是在我的代码中,IClock没有得到解决。我错过了什么吗?

class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();

if (!parameters.Any()) return Activator.CreateInstance(type);

var args = new List<object>();

foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}

var result = Activator.CreateInstance(type, args.ToArray());

return result;
}
}

public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}

public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}

public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}

public class AutoCue
{
private readonly IClock _clock;

public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}

最佳答案

您基本上实现的是一个能够自动连接对象图的小型 IoC 容器。但是您的实现只能创建具体对象的对象图。这会使您的代码违反 Dependency Inversion Principle .

实现中缺少的是某种 Register 方法,它告诉您的 AutomaticFactory 在遇到抽象时,它应该解析已注册的实现。这可能如下所示:

private static readonly Dictionary<Type, Type> registrations = 
new Dictionary<Type, Type>();

public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}

不,您还必须对 GetOne 方法进行调整。您可以在 GetOne 方法的开头添加以下代码:

    if (registrations.ContainsKey(type))
{
type = registrations[type];
}

这将确保如果提供的 typeAutomaticFactory 中注册为 TService,映射的 TImplementation将被使用,并且工厂将继续使用此实现作为要构建的类型。

但这确实意味着您现在必须显式注册 IClockSystemClock 之间的映射(如果您使用的是IoC 容器)。您必须在从 AutomaticFactory 解析第一个实例之前进行此映射。因此,您应该将以下行添加到 Main 方法的开头:

AutomaticFactory.Register<IClock, SystemClock>();

关于c#-4.0 - 在此示例中,IClock 如何使用 SystemClock 解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22713498/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com