简体   繁体   中英

How to register class as interface but invoke a method?

Following this blog I have copied the code below and it works fine, but I have modified it to suit my needs by creating an interface for DatabaseSettings and UserSettings with the same suffix by adding I to the current name. But the issue is that it is trying to register the interface as an interface which is wrong?

Before making the changes settings variables only have two entries now that I have added the interfaces settings is picking up the interface (because of the suffix) so it now has for entries instead of adding them as entries I would like to use them with the corresponding class and still invoke .LoadSection(type)

public class SettingsModule : Module
{
    private readonly string _configurationFilePath;
    private readonly string _sectionNameSuffix;

    public AeSettingsModule(string configurationFilePath, string sectionNameSuffix = "Settings")
    {
        _configurationFilePath = configurationFilePath;
        _sectionNameSuffix = sectionNameSuffix;
    }

    protected override void Load(ContainerBuilder builder)
    {

        var settings = Assembly.Load(nameof(DataLayer))
            .GetTypes()
            .Where(t => t.Name.EndsWith(_sectionNameSuffix, StringComparison.InvariantCulture))
            .ToList();

         settings.ForEach(type =>
         {
             builder.Register(c => c.Resolve<ISettingsReader>().LoadSection(type))
             .As(type)
             .SingleInstance();
         });
    }
}
public class DatabaseSettings: IDatabaseSettings
{
    public string ConnectionString { get;  set; }
    public int TimeoutSeconds { get; set; }
}

public interface IDatabaseSettings
{
    string ConnectionString { get; set; }
    int TimeoutSeconds { get; set; }
}

The error message I am getting is:

`System.MissingMethodException: 'Cannot create an instance of an interface.'`

Because I have changed the `Constructor injection from a class to an interface:

public UserService(IDatabaseSettings databaseSettings, IUserSettings userSettings)
{
    ...
}

Because I have added the interfaces and it has the same prefixes "Settings" it is picking up the interfaces which I don't wan, instead I would like to use it with the corresponding class?

I am trying to do this(but with the syntax above because I would like to invoke LoadSection too):

builder.RegisterType<DatabaseSettings>().As<IDatabaseSettings>();

I have found a solution through trial and error and the app works as expected but what I am not sure of is if it efficient, reliable etc.

I am posting merely to get feedback and if it is valid other might be able to use it.

var settings = Assembly.Load(nameof(DataLayer))
    .GetTypes()
    .Where(t => t.Name.EndsWith(_sectionNameSuffix, StringComparison.InvariantCulture ) && !t.IsInterface)
    .ToList();

    settings.ForEach(type =>
    {
        builder.Register(c => c.Resolve<ISettingsReader>().LoadSection(type))
            .As(type.GetInterfaces())
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM