带参数的构造函数注入

Constructor injection with Parameter

嗨,我正在尝试注册将 IDbConnection 作为构造函数参数的存储库 class。

public class Repository<TEntity> : IRepositoryAsync<TEntity> where TEntity : class
{
    public Repository(IDbConnection connection)
    {
        Connection = connection;
    }

    public IDbConnection Connection { get; }
}

我注册了这样的东西

var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();
container.Register(typeof(IRepositoryAsync<>), typeof(Repository<>));
container.Register(typeof(IDbConnection), typeof(Repository<User>));
    container.Register<IAuthService, AuthService>();
container.Verify();

我的代码哪里出了问题?

已更新 我收到如下异常

The constructor of type Repository contains the parameter with name 'connection' and type IDbConnection that is not registered. Please ensure IDbConnection is registered, or change the constructor of Repository.

更新 2

[ArgumentException: The supplied type Repository does not implement IDbConnection.Parameter name: implementationType]
SimpleInjector.Requires.ThrowSuppliedTypeDoesNotInheritFromOrImplement(Type service, Type implementation, String paramName) +63
SimpleInjector.Requires.ServiceIsAssignableFromImplementation(Type service, Type implementation, String paramName) +47
SimpleInjector.Container.Register(Type serviceType, Type implementationType, Lifestyle lifestyle, String serviceTypeParamName, String implementationTypeParamName) +159
SimpleInjector.Container.Register(Type serviceType, Type implementationType) +52
TimeTrackerService.Service.DependencyConfig..cctor() in D:\TimeTracking\TimeTrackerService\libs\TimeTrackerService.Service\DependencyConfig.cs:47[TypeInitializationException: The type initializer for 'TimeTrackerService.Service.DependencyConfig' threw an exception.]
TimeTrackerService.Service.DependencyConfig.get_Container() in D:\TimeTracking\TimeTrackerService\libs\TimeTrackerService.Service\DependencyConfig.cs:40 TimeTrackerService.WcfServiceFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses) in D:\TimeTracking\TimeTrackerService\TimeTrackerService\WcfServiceFactory.cs:15 System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +524
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +1420
System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +52
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +641[ServiceActivationException: The service '/TrackerService.svc' cannot be activated due to an exception during compilation. The exception message is: The type initializer for 'TimeTrackerService.Service.DependencyConfig' threw an exception..]
System.Runtime.AsyncResult.End(IAsyncResult result) +489035
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +174
System.ServiceModel.Activation.ServiceHttpModule.EndProcessRequest(IAsyncResult ar) +350322
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +9747521

最后我想出了解决办法。我没有注入 IDbConnection,而是注入了自己的实现接口。 IDataFactoryDataFactory。此实现 returns IDbConnection

private readonly string _providerName;
private readonly DbProviderFactory _provider;
public string ConnectionString { get; set; }

public DataFactory()
{
    var con = ConfigurationManager.ConnectionStrings["TrackerConnection"];
    if (con == null)
        throw new Exception("Failed to find connection");
    ConnectionString = con.ConnectionString;
    _providerName = con.ProviderName;
    _provider = DbProviderFactories.GetFactory(con.ProviderName);
}
public IDbConnection Connection
{
    get
    {
        var connection = _provider.CreateConnection();
        if (connection == null)
            throw new Exception($"Failed to create a connection using the connection string named '{_providerName}' in app.config or web.config.");
        connection.ConnectionString = ConnectionString;
        return connection;
    }
}

然后我注册了

container.Register<IDataFactory, DataFactory>();

现在我注入我的实现

public class Repository<TEntity> : IRepositoryAsync<TEntity> where TEntity : class
{
    public Repository(IDataFactory factory)
    {
        Factory= factory;
    }

    public IDataFactory Factory{ get; }
}

现在,当我使用 Factory.Connection 时,它会按预期工作

谢谢

另一种方式,避免添加自己的接口和实现。
将此覆盖用于 Register 方法:
Container.Register<TService>(Func<TService> instanceCreator, Lifestyle lifestyle)

像这样:

container.Register<IDbConnection>(() =>{ 
    var con = ConfigurationManager.ConnectionStrings["TrackerConnection"]; 
    if (con == null) 
        throw new Exception("Failed to find connection"); 

    var _provider = DbProviderFactories.GetFactory(con.ProviderName); 

    var connection = _provider.CreateConnection(); 
    if (connection == null) 
        throw new Exception($"Failed to create a connection using the connection string named '{con.ProviderName}' in app.config or web.config."); 

    connection.ConnectionString = con.ConnectionString; 
    return connection; 
});