我使用Unity来解决依赖关系。这是一个相当沉重的类,有一些相当重的依赖。它看起来像这样:
public interface IPicturesDownloader : IDownloadData { }
public interface IDataDownloader : IDownloadData { }
public interface ITextDownloader : IDownloadData { }
public interface IDownloadData
{
void Download();
}
public class HeavyClass : IHeavyClass
{
private readonly List<IDownloadData> _downloaders = new List<IDownloadData>();
public HeavyClass(
IPicturesDownloader a,
IDataDownloader b,
ITextDownloader c
/*etc*/)
{
_downloaders.Add(a);
_downloaders.Add(b);
_downloaders.Add(c);
}
public void DownloadEverything()
{
foreach (var downloader in _downloaders)
downloader.Download();
}
}
为了扩展实例化HeavyClass的加载,我制作了下载程序Lazy
:
public class HeavyLazyClass : IHeavyClass
{
private readonly List<Lazy<IDownloadData>> _downloaders = new List<Lazy<IDownloadData>>();
public HeavyLazyClass(
Lazy<IPicturesDownloader> a,
Lazy<IDataDownloader> b,
Lazy<ITextDownloader> c
/*etc*/)
{
_downloaders.Add(a);
_downloaders.Add(b);
_downloaders.Add(c);
}
public void DownloadEverything()
{
foreach (var downloader in _downloaders)
downloader.Value.Download();
}
}
然而,当使一切变得懒惰时会出现这个问题:
CS1503参数1:无法转换为&#39; System.Lazy&lt; My.Namespace.IPicturesDownloader&gt;&#39;到&#39; System.Lazy&lt; My.Namespace.IDownloadData&gt;&#39;
参数类型&#39; System.Lazy&lt; My.Namespace.IPicturesDownloader&gt;&#39;不能从&#39; System.Lazy&lt; My.Namespace.IDownloadData&gt;&#39;
分配
但是,人们会说:下载程序实现了所需的接口,因此这应该可行。为什么不完全没有,什么是最好/最简单的方法仍然使这项工作?它会极大地提高可用性。
我想我仍然可以回退到需要所有IDownloadData的构造函数(至少我认为如果配置正确,Unity可以解决这个问题):
public HeavyClass(IEnumerable<Lazy<IDownloadData>> dataDownloaders) {}
但这需要我重构一堆类和单元测试,以及统一配置。所以我宁愿省略它,并有一个更直接的解决方案。
我猜Why can I not assign a List of concrete types to a List of that concrete's interface?是同一个问题,但我想进一步解释。