dadhi / DryIoc

DryIoc is fast, small, full-featured IoC Container for .NET
MIT License
1.01k stars 123 forks source link

The member info IFreeSql Build() passed to `Made.Of` or `FactoryMethod.Of` is NOT static, but instance factory is not provided or null” #525

Closed sgf closed 2 years ago

sgf commented 2 years ago
        /// <summary>
        /// Singleton
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <param name="madeBy"></param>
        public void RegisterSingleton<TInterface>(System.Linq.Expressions.Expression<Func<TInterface>> madeBy)
        {
            container.Register<TInterface>(Reuse.Singleton, made: Made.Of(madeBy));
        }

    IocMgr.RegisterSingleton(() => new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.Sqlite, "test.db", null)
    .UseAutoSyncStructure(true)
    .UseMonitorCommand(cmd => Console.Write(cmd.CommandText), null)
    .Build());

Resolve<IFreeSql>();//got error
code: Error.PassedMemberIsNotStaticButInstanceFactoryIsNull;
message: The member info IFreeSql Build() passed to `Made.Of` or `FactoryMethod.Of` is NOT static, but instance factory is not provided or null”

The parameters of Register or MadeOf are complex for me to understand the logic.

is that because .Build() returned is an instance IFreeSql ?

what should i do

dadhi commented 2 years ago

Thanks for reporting. I will look.

dadhi commented 2 years ago

There are multiple problems here. First, whatvdo you wsnt to achieve? If you want to specify the delegate (chain of calls) to create the service then use the RegisterDelegate.

Your code without the RegisterSingleton maybe writing as following:

container.Register(ctx => new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.Sqlite, "test.db", null)
    .UseAutoSyncStructure(true)
    .UseMonitorCommand(cmd => Console.Write(cmd.CommandText), null)
    .Build(),
    Reusr.Singleton);

Second, Made.Of expression does not support the calls chain anyway - only single method or constructor call with optional property initializer list. Its goal is to provide the way to specify required service types, service keys or primitive values for injected parameters. Consider it as advanced thing and don't try to wrap this complexity - use when needed.

Think of Made.Of as advanced concept when you have some runtime reflection info

dadhi commented 2 years ago

@sgf Btw, if you see the lack of documentation please open the issue or suggest the edit.

sgf commented 2 years ago

use RegisterDelegate is the right way, many thanks

sgf commented 2 years ago

no lack of documentation,but the documentation also complex for me. 😂 if more easy,dryioc will more pop. any way,dryioc also great job.