Domanda

Sto cercando di utilizzare l'EntLib 3.1 al codice .NET per una DLL che è registrato per l'interoperabilità COM. Dove metto il file di configurazione?

In alternativa, c'è un modo per specificare all'interno del codice dll dove dovrebbe ottenere il config EntLib da? Dal momento che la mia dll sarà chiamato da COM Non sempre so cosa exe verrà chiamando.

Ho creato una semplice applicazione che utilizza la registrazione EntLib, con due classi: 'CallingApp' e 'MyComThing'. Quando chiamo un metodo di MyComThing da CallingApp si registra utilizzando la configurazione nel file di configurazione di CallingApp. Quando chiamo il metodo di MyComThing da uno script VBS, vale a dire attraverso COM, ottengo un errore "La sezione di configurazione per la registrazione non può essere trovato nella sorgente di configurazione". Il mio file COMThing.dll.config si trova nella stessa cartella del COMThing.dll registrato, vale a dire nella cartella bin \ debug \.

grazie!

È stato utile?

Soluzione

La risposta è che Enterprise Library di default usa file di configurazione del exe. Se si sta producendo una dll, tra cui COM, quindi per una buona ragione si potrebbe non voler dipendere l'eseguibile chiamante. Una soluzione a questo (ci potrebbero essere altri) è quello di crea gli oggetti di Enterprise Library invece di utilizzare quelli di default, e dire loro dove trovare la configurazione da. Questo non è così spaventoso come sembra e non richiede la ricompilazione EntLib o qualcosa di simile.

Invece di semplicemente usando Logger.Write () ho fatto la seguente: a) Creare l'autore della registrazione, utilizzando file di configurazione della DLL:

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

b) Quindi utilizzare questo scrittore registro all'interno del codice:

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

Ecco il codice completo per un oggetto campione che ho creato. I riferimenti erano 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;
        }
    }

}

Il progetto prevedeva un file COMThing.dll.config che ho impostato 'Copia nella directory di output' a 'Copia sempre'. Si tratta di una configurazione banale che scrive le informazioni nel registro eventi applicazioni di log. Il contenuto del file di configurazione sono:

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

Nelle proprietà del progetto sotto controllo Genera 'Registra per interoperabilità COM'. Il progetto, quindi creare il seguente file vbs:

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

Se si fa doppio clic su questo file di VBS dovrebbe mostrare una finestra di messaggio con il testo 'chiamato da com da VBS' e scrivere una voce al registro eventi applicazioni. Questo dimostra che, mentre il processo di esecuzione è C:. \ WINDOWS \ System32 \ WScript.exe (o simile), si sta facendo la configurazione dal file di configurazione del vostro dll

ho basato questo sulle informazioni qui sotto 'utilizzando diversi ConfigurationSources'.

Si noti che la classe Logger comprende un sacco di metodi di supporto bella con argomenti diversi. Dal momento che stiamo utilizzando la classe logwriter non otteniamo questa magia. Personalmente sarò creando un'altra classe all'interno della mia biblioteca per svolgere lo stesso lavoro, sulla base di Logger.

L'articolo citato illustra lo stesso principio applicato al database e applicazioni eccezione blocchi. Presumibilmente lo stesso modello può essere applicato alla maggior parte / tutti loro.

Altri suggerimenti

Controllare il problema relativo che avevo affrontato. Forse è di qualche aiuto.

Come includere componenti COM su un pubblicato. sito net?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top