【问题标题】:No suitable constructor when trying to create instance尝试创建实例时没有合适的构造函数
【发布时间】:2021-08-30 18:19:32
【问题描述】:

尝试使用依赖注入设置 .net 5 控制台应用程序并使用类库中的方法。不知道我已经解决了什么问题,但我得到了一个例外

'适合类型'TesterUtil.DataHelper.IBookMgr'的构造函数 无法定位。确保类型是具体的并且服务是 为公共构造函数的所有参数注册。'

主类

class Program
{


    static void Main(string[] args)
    {

        var host = AppStartup();
        var service = ActivatorUtilities.CreateInstance<IBookMgr>(host.Services);

        

        // test
        var results = service.GetDoTest();
        Console.WriteLine(results);

    }



    static IHost AppStartup()
    {

        var pathToExe = Process.GetCurrentProcess().MainModule.FileName;

        var configuration = new ConfigurationBuilder()
                                            .SetBasePath(Path.GetDirectoryName(pathToExe))
                                            .AddJsonFile("appsettings.json")
                                            .Build();



        LogManager.Configuration = new NLogLoggingConfiguration(configuration.GetSection("NLog"));


        var logger = NLog.Web.NLogBuilder.ConfigureNLog(LogManager.Configuration).GetCurrentClassLogger();
        logger.Info("Tester Startup");



        var host = Host.CreateDefaultBuilder() // Initialising the Host 
                    .ConfigureServices((context, services) =>
                    { // Adding the DI container for configuration
                        services.AddTransient<IBookMgr, BookMgr>();
                    })
                    .Build(); // Build the Host

        return host;
    }

图书管理员

public interface IBookMgr
{
    public bool GetDoTest();
    public bool SaveComplex();
}

public class BookMgr : IBookMgr
{

    private readonly DbContextOptionsBuilder<AdhocContext> _bldr1;
    private AdhocContext ctx;

    public BookMgr(IConfiguration config)
    {            
        // note extended commandtimeout settings, due to lengthy archive operations against Db
        _bldr1 = new DbContextOptionsBuilder<AdhocContext>();
        _bldr1.UseSqlServer(config.GetConnectionString("AdhocDbConStr"), sqlOptions => sqlOptions.CommandTimeout((int)TimeSpan.FromMinutes(20).TotalSeconds));
        ctx = new AdhocContext(_bldr1.Options);

        

    }
    public bool GetDoTest()
    {
        // test getting data
        bool retval = false;

        var TestList = (from a in ctx.Book select a).ToList();

        if(TestList.Count > 0)
        {
            retval = true;
        }
        else
        {
            retval = false;
        }

        return retval;

    }

    public bool SaveComplex()
    {
        bool retval = false;


        return retval;

    }

   
}

【问题讨论】:

    标签: .net dependency-injection


    【解决方案1】:

    直接从宿主的服务提供者解析所需的类型,

    //...
    
    IBookMgr service = host.Services.GetRequiredService<IBookMgr>();
    
    //...
    

    在这种情况下,ActivatorUtilities.CreateInstance 通常用于创建具体类型的实例,而不是 ActivatorUtilities.CreateInstance

    从这里的源代码可以看出

    /// <summary>
    /// Instantiate a type with constructor arguments provided directly and/or from an <see cref="IServiceProvider"/>.
    /// </summary>
    /// <param name="provider">The service provider used to resolve dependencies</param>
    /// <param name="instanceType">The type to activate</param>
    /// <param name="parameters">Constructor arguments not provided by the <paramref name="provider"/>.</param>
    /// <returns>An activated object of type instanceType</returns>
    public static object CreateInstance(IServiceProvider provider, Type instanceType, params object[] parameters)
    {
        int bestLength = -1;
        var seenPreferred = false;
    
        ConstructorMatcher bestMatcher = default;
    
        if (!instanceType.IsAbstract)
        {
            foreach (var constructor in instanceType.GetConstructors())
            {
                var matcher = new ConstructorMatcher(constructor);
                var isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false);
                var length = matcher.Match(parameters);
    
                if (isPreferred)
                {
                    if (seenPreferred)
                    {
                        ThrowMultipleCtorsMarkedWithAttributeException();
                    }
    
                    if (length == -1)
                    {
                        ThrowMarkedCtorDoesNotTakeAllProvidedArguments();
                    }
                }
    
                if (isPreferred || bestLength < length)
                {
                    bestLength = length;
                    bestMatcher = matcher;
                }
    
                seenPreferred |= isPreferred;
            }
        }
    
        if (bestLength == -1)
        {
            var message = $"A suitable constructor for type '{instanceType}' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.";
            throw new InvalidOperationException(message);
        }
    
        return bestMatcher.CreateInstance(provider);
    }
    

    Source code

    【讨论】:

    • 嗯,是的,是的,是时候再次查看文档了。谢谢
    猜你喜欢
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多