gpt4 book ai didi

c# - CaSTLe.Windsor 使用 Dapper 实例化错误版本的 SqlConnection

转载 作者:太空狗 更新时间:2023-10-30 01:34:07 24 4
gpt4 key购买 nike

当我们使用 CaSTLe.Windsor 来实例化一个类型化工厂的 SqlConnection 时,我们遇到了一个奇怪的问题:

注册看起来像这样:

container.Register(Component.For<IDbConnectionFactory>().AsFactory().LifestyleTransient());

container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.LifestyleTransient()
.DependsOn(Dependency.OnValue<string>
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));

IDbConnectionFactory:

public interface IDbConnectionFactory
{
IDbConnection Create();
void Release();
}

现在,当我尝试使用此代码访问新连接时:

using (var connection = _connectionFactory.Create())
{

}

我得到一个异常(exception):

An unhandled exception of type 
'Castle.MicroKernel.ComponentActivator.ComponentActivatorException' occurred
in Castle.Windsor.dll

Additional information: Error setting property SqlConnection.AccessToken in component
System.Data.SqlClient.SqlConnection. See inner exception for more information.

If you don't want Windsor to set this property you can do it by either decorating it
with DoNotWireAttribute or via registration API.

Alternatively consider making the setter non-public.

此异常的问题是 .NET 4.5.1 的 System.Data 中的类型 SqlConnection 不包含属性 AccessToken 而 .NET 4.6 中的类型做。换句话说,如果我尝试手动执行

var connection = new SqlConnection("connectionstring");
connection.AccessToken = "";

如果项目是为 .NET 4.5.1 配置的,我会收到构建错误,但如果项目是为 .NET 4.6 配置的,则会在设置 AccessToken 时出现运行时错误。

知道为什么 CaSTLe.Windsor 会尝试创建 v4.6 SqlConnection 而不是 .NET 4.5.1 吗?

解决方法/破解

我可以通过让 CaSTLe 忽略该属性来解决这个问题,但这似乎是一种 hack。这样做需要我将其添加到注册中的 PropertiesIgnore 中:

container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.PropertiesIgnore(info => info.Name.Equals("AccessToken"))
.LifestyleTransient()
.DependsOn(Dependency.OnValue<string>
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));

最佳答案

自 4.5 以来的所有 .NET 版本都已就位更新 as you can see here .

这意味着一旦您安装了 .NET 4.6,您将始终获得 .NET 4.6 版本的 SqlConnection,无论您如何实例化它。

在 Visual Studio 中构建应用程序时,您是针对特定版本的 .NET 框架构建的,该版本通常位于以下文件夹中:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework

这意味着在构建时 msbuild 可以检查您没有使用目标框架版本中不可用的东西。

但是,当您运行 64 位应用程序时,它将使用通常位于 C:\Windows\Microsoft.NET\Framework64\v4.0.30319 中的程序集

对于从 .NET 4.0 到 .NET 4.6 的所有版本,这是同一个文件夹,这就是就地升级的意思。

因此,当您在安装了 .NET 4.6 的开发环境中执行您的应用程序时,您将始终获得 .NET 4.6 版本(至少除非您执行一些特殊操作来加载其他版本的程序集)。

温莎城堡会尽力set properties with public setter它将使用反射来查找属性,这意味着它将在 .NET 4.6 机器上找到 .NET 4.6 属性,即使您是针对 4.5.1 构建的。

尝试设置 AccessToken 失败的原因很可能是因为您的连接字符串与设置 AccessToken 不兼容。

如果您检查 source code在 AccessToken setter 中,您会发现如果您尝试为不兼容的连接字符串设置它,它会抛出异常,即使您只是尝试将 AccessToken 设置为空字符串也是如此。

因为您不需要将任何依赖项注入(inject)到 SqlConnection 对象中,您也可以使用 new 运算符简单地创建它,然后避免因 Windsors 尝试注入(inject)连接属性而引起的问题。使用此注册应该有效:

container.Register(Component.For<IDbConnection>().ImplementedBy<SqlConnection>()
.LifestyleTransient()
.UsingFactoryMethod(() => new SqlConnection
(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)));

关于c# - CaSTLe.Windsor 使用 Dapper 实例化错误版本的 SqlConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31824995/

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