gpt4 book ai didi

dependency-injection - 如何开始使用 ASP.NET (5) Core 和 CaSTLe Windsor 进行依赖注入(inject)?

转载 作者:行者123 更新时间:2023-12-03 22:36:36 25 4
gpt4 key购买 nike

背景:

我根据 CaSTLe Windsor 教程使用早期版本的 MVC(6 之前)和 WebAPI 将 CaSTLe Windsor 与安装程序和设施一起使用。

ASP.NET (5) Core 包含了一些依赖注入(inject)支持,但我仍然没有弄清楚如何连接它,而且我发现的几个示例看起来与我以前使用它的方式有很大不同(使用安装人员/设施)。大多数示例早于 ASP.NET (5) 内核的最新版本,有些示例的信息似乎已过时。

与以前的版本组合根设置相比,它似乎发生了很大的变化,甚至没有 Microsoft.Framework.DependencyInjection.ServiceProvider当我将其设置为 CaSTLe Windsor DI 后备时,可以解决所有依赖项。我仍在深入研究细节,但没有太多最新信息。

我尝试将温莎城堡用于 DI

我找到了这样的适配器:Github Castle.Windsor DI container .

启动.cs

    private static IWindsorContainer container;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
container = new WindsorContainer();
app.UseServices(services =>
{
// ADDED app.ApplicationServices FOR FALLBACK DI
container.Populate(services, app.ApplicationServices);
container.BeginScope();
return container.Resolve<IServiceProvider>();
});
// ... default stuff

WindsorRegistration.cs
我添加了几行来添加城堡温莎 ILazyComponentLoader倒退。

using Castle.MicroKernel.Lifestyle;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
using Castle.Windsor;
using Microsoft.Framework.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Notes.Infrastructure
{
/// <summary>
/// An adapted current autofac code to work with Castle.Windsor container.
/// https://github.com/aspnet/Home/issues/263
/// </summary>
public static class WindsorRegistration
{
public static void Populate(
this IWindsorContainer container,
IEnumerable<IServiceDescriptor> descriptors,
IServiceProvider fallbackProvider // ADDED FOR FALLBACK DI
)
{
// ADDED FOR FALLBACK DI
// http://davidzych.com/2014/08/27/building-the-castle-windsor-dependency-injection-populator-for-asp-net-vnext/
// Trying to add a fallback if Castle Windsor doesn't find the .NET stuff
var fallbackComponentLoader = new FallbackLazyComponentLoader(fallbackProvider);
container.Register(Component.For<ILazyComponentLoader>().Instance(fallbackComponentLoader));

// Rest as usual from the Github link
container.Register(Component.For<IWindsorContainer>().Instance(container));
container.Register(Component.For<IServiceProvider>().ImplementedBy<WindsorServiceProvider>());
container.Register(Component.For<IServiceScopeFactory>().ImplementedBy<WindsorServiceScopeFactory>());

container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

Register(container, descriptors);
}

private static void Register(
IWindsorContainer container,
IEnumerable<IServiceDescriptor> descriptors)
{
foreach (var descriptor in descriptors)
{
if (descriptor.ImplementationType != null)
{
// Test if the an open generic type is being registered
var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo();
if (serviceTypeInfo.IsGenericTypeDefinition)
{
container.Register(Component.For(descriptor.ServiceType)
.ImplementedBy(descriptor.ImplementationType)
.ConfigureLifecycle(descriptor.Lifecycle)
.OnlyNewServices());
}
else
{
container.Register(Component.For(descriptor.ServiceType)
.ImplementedBy(descriptor.ImplementationType)
.ConfigureLifecycle(descriptor.Lifecycle)
.OnlyNewServices());
}
}
else if (descriptor.ImplementationFactory != null)
{
var service1 = descriptor;
container.Register(Component.For(descriptor.ServiceType)
.UsingFactoryMethod<object>(c =>
{
var builderProvider = container.Resolve<IServiceProvider>();
return
service1.ImplementationFactory(builderProvider);
})
.ConfigureLifecycle(descriptor.Lifecycle)
.OnlyNewServices());
}
else
{
container.Register(Component.For(descriptor.ServiceType)
.Instance(descriptor.ImplementationInstance)
.ConfigureLifecycle(descriptor.Lifecycle)
.OnlyNewServices());
}
}
}

private static ComponentRegistration<object> ConfigureLifecycle(
this ComponentRegistration<object> registrationBuilder,
LifecycleKind lifecycleKind)
{
switch (lifecycleKind)
{
case LifecycleKind.Singleton:
registrationBuilder.LifestyleSingleton();
break;

case LifecycleKind.Scoped:
registrationBuilder.LifestyleScoped();
break;

case LifecycleKind.Transient:
registrationBuilder.LifestyleTransient();
break;
}

return registrationBuilder;
}

private class WindsorServiceProvider : IServiceProvider
{
private readonly IWindsorContainer _container;

public WindsorServiceProvider(IWindsorContainer container)
{
_container = container;
}

public object GetService(Type serviceType)
{
return _container.Resolve(serviceType);
}
}

private class WindsorServiceScopeFactory : IServiceScopeFactory
{
private readonly IWindsorContainer _container;

public WindsorServiceScopeFactory(IWindsorContainer container)
{
_container = container;
}

public IServiceScope CreateScope()
{
return new WindsorServiceScope(_container);
}
}

private class WindsorServiceScope : IServiceScope
{
private readonly IServiceProvider _serviceProvider;
private readonly IDisposable _scope;

public WindsorServiceScope(IWindsorContainer container)
{
_scope = container.BeginScope();
_serviceProvider = container.Resolve<IServiceProvider>();
}

public IServiceProvider ServiceProvider
{
get { return _serviceProvider; }
}

public void Dispose()
{
_scope.Dispose();
}
}
}
}

第一次打嗝和解决尝试

从那个例子我得到:

CaSTLe.Windsor.dll 中出现“CaSTLe.MicroKernel.ComponentNotFoundException”类型的异常,但未在用户代码中处理
附加信息:找不到支持服务 Microsoft.Framework.Runtime.IAssemblyLoaderEngine 的组件

无法在 CaSTLe Fallback 的调试器中查看 - Microsoft.Framework.DependencyInjection.ServiceProvider (服务表)。

来自 http://davidzych.com/tag/castle-windsor/由于 Windsor 无法解决所有 ASP.NET 依赖项,因此我尝试添加一个后备。

FallbackLazyComponentLoader.cs

/// <summary>
/// https://github.com/davezych/DependencyInjection/blob/windsor/src/Microsoft.Framework.DependencyInjection.Windsor/FallbackLazyComponentLoader.cs
/// </summary>
public class FallbackLazyComponentLoader : ILazyComponentLoader
{
private IServiceProvider _fallbackProvider;

public FallbackLazyComponentLoader(IServiceProvider provider)
{
_fallbackProvider = provider;
}

public IRegistration Load(string name, Type service, IDictionary arguments)
{
var serviceFromFallback = _fallbackProvider.GetService(service);
if (serviceFromFallback != null)
{
return Component.For(service).Instance(serviceFromFallback);
}
return null;
}
}

这似乎是必要的(注入(inject)所有 .NET 依赖项)

我可以注释掉 startup.cs app.UseBrowserLink();摆脱 IAssemblyLoaderEngine 异常。

        if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
{
//app.UseBrowserLink(); //

现在我遇到了一个异常:

mscorlib.dll 中出现“System.Reflection.TargetInvocationException”类型的异常,但未在用户代码中处理

尝试获取服务:{Name = "IUrlHelper"FullName = "Microsoft.AspNet.Mvc.IUrlHelper"}

    public IRegistration Load(string name, Type service, IDictionary arguments)
{
var serviceFromFallback = _fallbackProvider.GetService(service);

如何前进?

将 CaSTLe Windsor DI 连接到 ASP.NET (5) Core 的尝试有什么问题?

最佳答案

目前我认为您不能使用 CaSTLe Windsor Container 作为 DI 容器,因为 Windsor 不支持新的 DNVM .但是 AutoFac 确实如此,并且它们遵循相同的规则。

在 Startup.cs 中有一个 ConfigureServices返回类型为 void 的方法。您可以将返回类型更改为 ISerivceProvider并返回一个具体的 IServiceProvider ,系统将使用新的IServiceProvider作为默认的 DI 容器。下面是 AutoFac 示例。

public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));
services.AddMvc();

var builder = new ContainerBuilder();
AutofacRegistration.Populate(builder, services);
var container = builder.Build();
return container.Resolve<IServiceProvider>();
}

其他 DI 适配器也实现了类似的接口(interface)。您可以自己尝试,但请注意 AutoFac 现在处于 beta5 中,因此您需要进行一些调整以使您的应用程序运行。

希望这可以帮助

关于dependency-injection - 如何开始使用 ASP.NET (5) Core 和 CaSTLe Windsor 进行依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28353187/

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