Pregunta

Estoy tratando de utilizar el EntLib 3.1 del código .NET de un archivo DLL que se registra para la interoperabilidad COM. ¿Dónde pongo el archivo de configuración?

Por otra parte, ¿hay una forma de especificar dentro del código DLL donde debe obtener la configuración de EntLib? Desde mi DLL se llamará a partir de COM no siempre sé lo exe estará llamando a él.

He creado una aplicación sencilla que utiliza registro EntLib, con dos clases: 'CallingApp' y 'MyComThing'. Cuando llamo a un método de MyComThing de CallingApp registra utilizando la configuración en el archivo de configuración de CallingApp. Cuando llamo el método de MyComThing desde un script vbs, es decir, a través de COM, consigo un error "La sección de configuración para el registro no se puede encontrar en la fuente de configuración". Mi archivo COMThing.dll.config está en la misma carpeta que el COMThing.dll registrado, es decir, en el bin \ debug \ carpeta.

Gracias!

¿Fue útil?

Solución

La respuesta es que Enterprise Library por defecto usa el archivo de configuración del exe. Si usted está produciendo una DLL, incluyendo COM, a continuación, por una buena razón puede que no quieren depender del ejecutable llamado. Una solución a este (puede haber otros) es la creación de objetos de Enterprise Library a sí mismo en lugar de utilizar la falta de pago, y decirles dónde obtener la configuración de. Esto no es tan difícil como parece y no es necesario volver a compilar EntLib ni nada de eso.

En lugar de simplemente utilizar Logger.Write () hice lo siguiente: a) Crear el escritor de registro, utilizando el archivo de configuración del archivo DLL:

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

b) A continuación, utilice este escritor de registro dentro de su código:

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

Aquí está el código completo para un objeto de muestra que he creado. Las referencias fueron Microsoft.Practices.EnterpriseLibrary.Common, Microsoft.Practices.EnterpriseLibrary.Logging, Microsoft.Practices.ObjectBuilder, Sistema, System.Data, System.Windows.Forms, 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;
        }
    }

}

El proyecto incluye un archivo COMThing.dll.config cual di 'Copiar al Directorio de salida' a 'Copia siempre'. Esta es una configuración trivial de que escribe la información en el registro de sucesos de aplicación. El contenido del archivo de configuración son:

<?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>

En las propiedades del proyecto en virtud de verificación Generar 'Register para interoperabilidad COM'. La construcción del proyecto, a continuación, crear el siguiente archivo .vbs:

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

Si hace doble clic en este archivo de VBS debe mostrar un cuadro de mensaje con el texto 'llamada de com por vbs' y escribir una entrada en su Solicitud de Registro de eventos. Esto demuestra que, si bien el proceso de ejecución es C:. \ WINDOWS \ System32 \ WScript.exe (o similar), se está haciendo la configuración del archivo de configuración de su DLL

I basado esto en la información aquí en 'el uso de varios ConfigurationSources'.

Tenga en cuenta que la clase Logger incluye gran cantidad de métodos de ayuda agradables con diferentes argumentos. Puesto que estamos utilizando la clase LogWriter no obtenemos esta magia. Personalmente me va a crear otra clase dentro de mi biblioteca para realizar el mismo trabajo, basado en Logger.

El artículo de referencia muestra el mismo principio se aplica a la base de datos y de la aplicación Excepción bloques. Es de suponer que el mismo modelo se puede aplicar a la mayoría / todos ellos.

Otros consejos

Comprobar el tema relacionado que me había enfrentado. Tal vez sea de alguna ayuda.

Cómo incluir componentes COM en una publicación. sitio de red?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top