По запросу синглтоны. Любопытно узнать, если это плохая практика, и какой лучший способ достижения моей цели - PullRequest
0 голосов
/ 07 января 2019

При создании страниц в ASP.Net Core мне часто приходится выполнять кучу работ, которые должны выполняться только при запуске, например, загружать файл JSON с диска, который будет содержать некоторые данные, обычно только одним RazorPage.

Для этого обычно делают следующее:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddSingleton(typeof(SingletonThatLoadsStaticDataFromAJSONFile));
    // ...
}

SingletonThatLoadsStaticDataFromAJSONFile.cs

public class SingletonThatLoadsStaticDataFromAJSONFile
{
    public SomeData SomeData;

    public SingletonThatLoadsStaticDataFromAJSONFile(IHostingEnvironment env)
    {
        var path = Path.Combine(env.ContentRootPath, "PathToJSONFile");
        this.SomeData = Deserialize(path);
    }
}


Чтобы сделать мою жизнь немного проще, я создал атрибут, который позволяет мне делать это без особых усилий. Таким образом, мне не нужно постоянно добавлять do services.AddSingleton (typeof (x)), и я могу легко удалить папку RazorPages без ошибок компиляции.

SingletonAttribute.cs

public class SingletonAttribute : Attribute
{
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...
    var singletonTypes = typeof(Program).Assembly
        .GetTypes()
        .Where(x => x.IsClass && x.GetCustomAttributes().OfType<SingletonAttribute>().Any());

    foreach (var type in singletonTypes)
    {
        services.AddSingleton(type);
    }
    // ...
}

Так что мне интересно, что вы, ребята, делаете в подобных ситуациях, есть ли лучший способ сделать это.

Сноска. Я не делаю крупномасштабный веб-сайт, поэтому меня не волнуют лучшие практики использования интерфейсов и масштабируемости.

1 Ответ

0 голосов
/ 07 января 2019

Концепция в порядке. Я бы улучшил формулировку.

Из-за совпадения формулировок я бы не назвал ваш атрибут Singleton. Он не говорит о том, что на самом деле делает, и худший случай неправильно понимается как реализация шаблона Singleton (anti-).

Почему бы не назвать его AutomaticallyAddedToServicesAsSingletonAttribute, чтобы вы могли комментировать свой класс следующим образом:

[AutomaticallyAddedToServicesAsSingleton]
public class FoobarReferenceDataReader
{
    //...
}

Теперь совершенно ясно, что это делает.

...