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

本文关键字:gt lt 参数 何注册 Func 注册 | 更新日期: 2023-09-27 18:28:34

我有以下代码:

_container = new UnityContainer();
_container.RegisterType<IDownloader, Downloader>();
_container.RegisterType<INewObject, NewObject>();
_container.RegisterType<SearchViewModel>();

带有构造函数注入的SearchViewModel类:

class SearchViewModel
{
    private readonly Func<IDownloader> _downloaderFactory;
    private readonly INewObject _newObject;
    private IDownloader _downloader;
    public SearchViewModel(Func<IDownloader> downloaderFactory, INewObject newObject)
    {
        _downloaderFactory = downloaderFactory;
        _newObject = newObject;
    }        
}

问题:如何注册以Fun<>为参数的SearchViewModel

_container.RegisterType<SearchViewModel>(new InjectionConstructor(DownloaderFactory()));

上面的代码仅在没有INewObject的情况下工作。

目标:使用InjectionConstructor解析工厂,并自动解析INewObject, INewObject2, INewObject3(如无参数:RegisterType<SearchViewModel>())。

有可能吗?也许是候补?

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

我已经解决了问题:

_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            new Func<IDownloader> (() => _container.Resolve<IDownloader>())));
_container.RegisterType<SearchViewModel>();

新的Func是一个关键,因为在我尝试之前:

_container.RegisterType<Func<IDownloader>>(new InjectionFactory(i => 
            _container.Resolve<IDownloader>()));

用CCD_ 8代替CCD_。IDownloaderFactory可以封装委托。

此外,我认为在工厂内部使用委托作为依赖关系比破坏CompositionRoot是更好的解决方案。

这里通常使用的模式是声明一个抽象工厂,并使其更加明确:

 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>();
     }
 }

使用这种方法更明确,可以更好地处理容器,而且它仍然使容器远离您的应用程序和业务逻辑,现在您只需要对SearchViewModel类进行一个小的调整:

class SearchViewModel
{
   private readonly IDownloaderFactory _downloaderFactory;
   private readonly INewObject _newObject;
   public SearchViewModel(IDownloaderFactory downloaderFactory, INewObject newObject)
   {
       _downloaderFactory = downloaderFactory;
       _newObject = newObject;
       Console.WriteLine(downloaderFactory.Create().GetHashCode());
       Console.WriteLine(downloaderFactory.Create().GetHashCode());
   }

}

现在,您可以看到它只是工作,每次都会创建新的实例。

设置容器如下所示:

        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>();

请注意,您需要注册正在使用的容器的实例,以便工厂使用此方法或ThreadLocal实例化或其他方法获得相同的实例。

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