C# 如何注册具有`Func<>;`作为参数?

C# 如何注册具有`Func<>;`作为参数?,c#,dependency-injection,unity-container,C#,Dependency Injection,Unity Container,我有以下代码: _container = new UnityContainer(); _container.RegisterType<IDownloader, Downloader>(); _container.RegisterType<INewObject, NewObject>(); _container.RegisterType<SearchViewModel>(); 问题:如何注册具有Fun作为参数的SearchViewModel _containe

我有以下代码:

_container = new UnityContainer();
_container.RegisterType<IDownloader, Downloader>();
_container.RegisterType<INewObject, NewObject>();
_container.RegisterType<SearchViewModel>();
问题:如何注册具有
Fun
作为参数的
SearchViewModel

_container.RegisterType<SearchViewModel>(new InjectionConstructor(DownloaderFactory()));
\u container.RegisterType(新注入构造函数(DownloaderFactory());
上述代码仅在不使用
INewObject
的情况下有效

目标:使用
注入构造函数解析工厂
并自动解析
INewObject、INewObject 2、INewObject 3
(如无参数:
RegisterType()


可能吗?可能替代?

这里使用的普遍接受的模式是声明一个抽象工厂,并使其更加明确:

 public interface IDownloaderFactory
 {
    IDownloader Create();
 }
然后创建一个类来表示工厂,该工厂只需再次使用容器来解析实例:

 public class DownloaderFactory : IDownloaderFactory
 {
     private UnityContainer _Container;
     public DownloaderFactory(UnityContainer container)
     {
         this._Container = container;
     }

     public IDownloader Create()
     {
         return this._Container.Resolve<IDownloader>();
     }
 }
}

现在,您可以看到它每次都工作并创建新实例

设置容器将如下所示:

        var container = new UnityContainer();
        container.RegisterType<IDownloader, Downloader>();
        container.RegisterType<INewObject, NewObject>();
        container.RegisterType<IDownloaderFactory, DownloaderFactory>();
        container.RegisterType<SearchViewModel>();
        container.RegisterInstance(container);
        var model = container.Resolve<SearchViewModel>();
var container=newunitycontainer();
container.RegisterType();
container.RegisterType();
container.RegisterType();
container.RegisterType();
容器。注册表状态(容器);
var model=container.Resolve();
请注意,您需要注册正在使用的容器的实例,以便工厂使用此方法或ThreadLocal实例或其他方法获取相同的实例

注意:
还需要注意的是,使用Func方法或使用容器解析下载程序可能会在您的客户机中造成不希望的效果。例如,如果容器默认设置为对Downloader的对象是瞬态的,那么每次都会创建一个新实例。更改容器上的生存期可能会导致客户端每次都获得相同的实例。在这种情况下,最好在工厂中手动构造downloader对象,并仅将容器用于downloader的参数。

我已经解决了这个问题:

_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            new Func<IDownloader> (() => _container.Resolve<IDownloader>())));
_container.RegisterType<SearchViewModel>();
\u container.RegisterType(新注入工厂(i=>
新函数(()=>_container.Resolve());
_container.RegisterType();
new Func是一个键,因为在我尝试之前:

_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            _container.Resolve<IDownloader>()));
\u container.RegisterType(新注入工厂(i=>
_container.Resolve());
另外,使用
IDownloaderFactory
而不是
Func downloaderFactory
的更好方法
IDownloaderFactory
可以封装委托


此外,我认为在工厂内使用委托作为依赖项比使用断开的组合根更好

为什么不将Setter注入用于不平等的对象参数?为什么使SearchViewModel依赖于Func?这不是漏洞百出的抽象吗?我认为应该直接注入IDownloader接口。IDownloader的具体实现可以封装工厂行为。请参见此处的代码示例:brilliant。它就像一个符咒,帮助我在一个遗留项目中获得了与我以前从Autofac for freeRegisterType获得的相同的经验。现在,该类型被标记为过时。相反,使用_container.RegisterFactory(c=>c.Resolve());
_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            new Func<IDownloader> (() => _container.Resolve<IDownloader>())));
_container.RegisterType<SearchViewModel>();
_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            _container.Resolve<IDownloader>()));