Применение Autofac в консольном приложении C# .NET

188
23 февраля 2019, 20:30

Решил пощупать на практике Autofac. Но не хватает знаний для его применения. Проект простой, взял за основу работу с последовательным портом. Создал модель

public class SerialPortSettings 
{ 
    public string Port { get; set; }
    public int BaudRate { get; set; }
    public int DataBits { get; set; }
    public Parity Parity { get; set; }
    public StopBits StopBits { get; set; }
    public string ThreadControl { get; set; }
    public int ReadTimeOut { get; set; }
    public SerialPortSettings()
    {
      // Инициализация свойств и присвоение настроек порта  
    }
}

Интерфейс

public interface ISerialPortService
{
    void SetPort();
    void WriteData(string msg);
    bool OpenPort();
    bool ClosePort();
}

Реализация (весь класс не буду приводить в рамках экономии места)

public class SerialPortService : ISerialPortService, IDisposable
{
    private SerialPortSettings _portSettings;
    private SerialPort _comPort;
    public TransmissionType CurrentTransmissionType { get; set; }
    public string RecievedText { get; set; }
    public string PortStatus { get; set; }
    public event DataRecievedEventHandler DataChanged;
    public delegate void DataRecievedEventHandler(object sender, string package);
    public SerialPortService()
    {
        _portSettings = new SerialPortSettings();
        _comPort = new SerialPort();
        _comPort.DataReceived += comPort_DataReceived;
    }

Ну и в мейн я просто работаю с объектами SerialPortService

class Program
{
    static SerialPortService portService = new SerialPortService();
    static void Main(string[] args)
    {
        portService.OpenPort();
        Console.WriteLine(portService.PortStatus);
        Console.WriteLine(portService.RecievedText);
        Console.ReadKey();
        portService.ClosePort();
    }

Создал отдельный класс для настройки Autogac и тут не понимаю как все это дело правильно настроить (а может я уже и так верно все сделал).

public class AutofacSetup
{
    public static void ConfigureContainer()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<SerialPortService>()
            .As<ISerialPortService>();
        builder.Build();
    }
}

И что дальше с ним делать?

Answer 1

Вам нужно вернуть результат работы метода Build():

public static IContainer ConfigureContainer()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<SerialPortService>()
        .As<ISerialPortService>();
    return builder.Build();
}

Теперь можно использовать контейнер для того чтобы достать из него сервисы:

var container = AutofacSetup.ConfigureContainer();
var service = container.Resolve<ISerialPortService>();
service.OpenPort();

Видите, насколько программа упростилась? (это был сарказм)

Для того, чтобы выгода от использования Autofac была ощутима, у вас должны быть классы с зависимостями. Много классов с зависимостями. Пока что у вас есть всего 1 класс в котором нет ни одной зависимости, так что польза от Autofac сомнительна.

Также напоминаю, что в нормальной архитектуре построенный контейнер не должен покидать пределы Composition Root (у вас в роли Сomposition Root выступает, скорее всего, метод Main).

Answer 2

Замените

static SerialPortService portService = new SerialPortService(); 

на строчку:

private static ISerialPortService portService { get; set; }

А в Main добавьте вызов autofac. Он вам в portService будет подставлять на место абстрактного интерфейса ISerialPortService конкретную реализацию SerialPortService.

Я вообще предпочитаю Main держать чистым - поэтому вынес бы из него всю логику работы приложения, оставив только вызов autofac:

static void Main(string[] args)
{
    ConfigureContainer();
    Execute();
}
static void Execute()
{
    portService.OpenPort();
    Console.WriteLine(portService.PortStatus);
    Console.WriteLine(portService.RecievedText);
    Console.ReadKey();
    portService.ClosePort();
}

Код ConfigureContainer посмотрите в соседнем ответе, не буду переписывать одно и то же.

READ ALSO
Хеш-таблица (Hashtable) на языке C#. Для чего она?

Хеш-таблица (Hashtable) на языке C#. Для чего она?

Изучаю теорию, подскажите, какое практическое применение Hashtable

140
Как повысить права C# Linux

Как повысить права C# Linux

Надо в определенный момент работы программы установить в операционку корневой сертификатСоответственно для этого нужно повысить права...

163