Entlib и взаимодействие:работает ли это, и куда девается конфигурационный файл?

StackOverflow https://stackoverflow.com/questions/359354

Вопрос

Я пытаюсь использовать EntLib 3.1 в коде .net для библиотеки dll, которая зарегистрирована для COM-взаимодействия.Куда мне поместить конфигурационный файл?

В качестве альтернативы, есть ли способ указать в коде dll, откуда он должен получить конфигурацию entlib?Поскольку моя библиотека dll будет вызываться из COM, я не всегда знаю, какой exe-файл будет ее вызывать.

Я создал простое приложение, которое использует ведение журнала entlib, с двумя классами:"CallingApp" и "MyComThing".Когда я вызываю метод MyComThing из CallingApp, он регистрируется, используя конфигурацию в конфигурационном файле CallingApp.Когда я вызываю метод MyComThing из скрипта vbs, т.е. через COM, я получаю сообщение об ошибке "Раздел конфигурации для ведения журнала не может быть найден в источнике конфигурации".Мой файл COMThing.dll.config находится в той же папке, что и зарегистрированный COMThing.dll, т.е. в папке bin \debug\.

Спасибо!

Это было полезно?

Решение

Ответ заключается в том, что Enterprise Library по умолчанию использует конфигурационный файл exe.Если вы создаете библиотеку DLL, включая COM, то по уважительной причине вы, возможно, не захотите зависеть от вызывающего исполняемого файла.Одним из решений этой проблемы (могут быть и другие) является самостоятельное создание объектов Enterprise Library вместо использования объектов по умолчанию и указание им, откуда брать конфигурацию.Это не так страшно, как кажется, и не требует перекомпиляции entlib или чего-то подобного.

Вместо того, чтобы просто использовать Logger.Write () Я сделал следующее:a) Создайте программу записи журнала, используя конфигурационный файл библиотеки dll:

        string dllConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
        FileConfigurationSource exceptionsSource = new FileConfigurationSource(dllConfigFilename);
        LogWriterFactory writerFactory = new LogWriterFactory(exceptionsSource);
        logWriter = writerFactory.Create();

б) Затем используйте этот журнал записи в вашем коде:

        LogEntry log = new LogEntry();
        log.Message = message;
        log.Categories = new string[] { "General" };
        logWriter.Write(log);

Вот полный код для примера объекта, который я создал.Ссылки были на Microsoft.Практика.EnterpriseLibrary.Распространенная, Microsoft.Практика.EnterpriseLibrary.Ведение журнала, Microsoft.Практика.ObjectBuilder, Система, System.Данные, System.Windows.Формы, System.Xml:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace COMThing
{
    [ComVisible(true)]
    public class MyComThing : MyComInterface
    {
        LogWriter logWriter; 

        public MyComThing()
        {
            string dllConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
            FileConfigurationSource exceptionsSource = new FileConfigurationSource(dllConfigFilename);
            LogWriterFactory writerFactory = new LogWriterFactory(exceptionsSource);
            logWriter = writerFactory.Create();
        }

        public bool ProcessMessage(string message)
        {
            LogEntry log = new LogEntry();
            log.Message = message;
            log.Categories = new string[] { "General" };
            logWriter.Write(log);
            MessageBox.Show(message);
            return true;
        }
    }

}

Проект включал файл COMThing.dll.config, для которого я установил 'Копировать в выходной каталог' значение 'Копировать всегда'.Это тривиальная конфигурация, которая записывает информацию журнала в журнал событий приложения.Содержимое конфигурационного файла является:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add source="COMThing Logger" formatter="Text Formatter" log="Application"
        machineName="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Formatted EventLog TraceListener" />
    </listeners>
    <formatters>
      <add template="Timestamp: {timestamp}&#xD;&#xA;Message: {message}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {appDomain}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}&#xD;&#xA;)}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
</configuration>

В свойствах проекта в разделе Сборка установите флажок "Зарегистрироваться для COM-взаимодействия".Создайте проект, затем создайте следующий файл .vbs:

Set obj = CreateObject("COMThing.MyComThing")
obj.ProcessMessage("called from com by vbs")

Если вы дважды щелкните этот файл vbs, он должен отобразить окно сообщения с текстом "вызвано из com vbs" и внести запись в журнал событий вашего приложения.Это демонстрирует, что во время выполнения процесса C:\WINDOWS\System32\WScript.exe (или аналогичного) он получает конфигурацию из файла конфигурации вашей библиотеки dll.

Я основал это на полученной информации здесь в разделе "Использование нескольких конфигурационных источников".

Обратите внимание, что класс Logger включает в себя множество полезных вспомогательных методов с различными аргументами.Поскольку мы используем класс LogWriter, мы не получаем этой магии.Лично я создам другой класс в своей библиотеке для выполнения той же работы на основе Logger.

В статье, на которую даны ссылки, показан тот же принцип, применяемый к блокам приложений базы данных и исключений.Предположительно, одна и та же модель может быть применена к большинству / всем из них.

Другие советы

Проверьте связанную с этим проблему, с которой я столкнулся.Может быть, это как-то поможет.

Как включить COM-компоненты на опубликованный сайт .Net?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top