f # Получить определение общего типа для типа с ограничениями - PullRequest
1 голос
/ 02 февраля 2012

вот конечная цель: получить новое соединение от фабрики по имени, например, так: factory.CreateConnection<SqlConnection>("my db")

Вот мой код:

type IConnectionFactory =
    abstract member CreateConnection : unit -> IDbConnection

type DefaultConnectionFactory<'t when 't : (new : unit -> 't) and 't :> IDbConnection> () =
    member this.CreateConnection () = new 't()

    interface IConnectionFactory with
        member this.CreateConnection () = this.CreateConnection() :> IDbConnection

type DefaultConnectionFactoryFactory() =
    member this.CreateConnectionFactory connectionType =
        if not (typeof<IDbConnection>.IsAssignableFrom connectionType)
        then invalidArg "connectionType" (sprintf "type %O is not assignable to IDbConnection" connectionType)

        let genericFactoryType = typedefof<DefaultConnectionFactory<_>>
        let factorytype = genericFactoryType.MakeGenericType([| connectionType |])
        Activator.CreateInstance(factorytype) :?> IConnectionFactory

type ConnectionFactory (connectionStrings : Dictionary<string, (IConnectionFactory * string)>) =
    let ConnectionStrings = connectionStrings

    member this.CreateConnection connectionStringName : 't :> IDbConnection =
        if ConnectionStrings.ContainsKey connectionStringName
        then
            let connectionFactory, connectionString = ConnectionStrings.Item connectionStringName
            let connection = connectionFactory.CreateConnection ()
            connection.ConnectionString <- connectionString
            connection :?> 't
        else invalidArg "dataSourceName" (sprintf "no data source found named %s" connectionStringName)

в этой строке:

let genericFactoryType = typedefof<DefaultConnectionFactory<_>>

Я получаю эту ошибку: Несоответствие ограничения типа при применении типа по умолчанию 'IDbConnection' для переменной вывода типа.Общая конструкция требует, чтобы у типа 'IDbConnection' был общедоступный конструктор по умолчанию. Рассмотрите возможность добавления дополнительных ограничений типов

Я не уверен, как ее разрешить ... Любые другие предложения также приветствуются

1 Ответ

3 голосов
/ 02 февраля 2012

Это как-то связано с этим вопросом . Проблема в typedefof<DefaultConnectionFactory<_>>. Ограничение на DefaultConnectionFactory требует тип, который реализует IDbConnection и имеет конструктор по умолчанию. Компилятор не знает такого типа. Итак, вам придется предоставить один. Вы можете использовать SqlConnection, например:

typedefof<DefaultConnectionFactory<System.Data.SqlClient.SqlConnection>>

Эффект тот же. typedefof вернет неограниченный тип DefaultConnectionFactory<> (в терминах C #), который невозможно выразить в F #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...