EntLib e interoperabilidade: é que funciona, e onde é que o movimento arquivo de configuração?

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

Pergunta

Eu estou tentando usar o EntLib 3.1 no código .net para uma dll que está registrado para interoperabilidade. Onde devo colocar o arquivo de configuração?

Como alternativa, há uma maneira para especificar dentro do código dll onde ele deve obter a configuração EntLib de? Desde a minha dll vai ser chamado a partir COM eu nem sempre sabe o exe será chamando-o.

Eu criei um aplicativo simples que usa Logging EntLib, com duas classes: 'CallingApp' e 'MyComThing'. Quando eu chamar um método de MyComThing de CallingApp ele registra usando a configuração no arquivo de configuração do CallingApp. Quando eu chamar o método de MyComThing partir de um script vbs, ou seja, através COM, eu recebo um erro "A seção de configuração para Logging não pode ser encontrado na fonte de configuração". Meu arquivo COMThing.dll.config está na mesma pasta que o COMThing.dll registrado, ou seja, no bin \ debug \ pasta.

Obrigado!

Foi útil?

Solução

A resposta é que Enterprise Library por padrão usa o arquivo de configuração do exe. Se você está produzindo uma dll, incluindo COM, em seguida, por uma boa razão você não pode querer depender do executável chamado. Uma solução para isso (pode haver outros) é criar o Enterprise Library objetos si mesmo em vez de usar os default, e dizer-lhes onde obter a configuração de. Esta não é tão assustador quanto parece e não requer recompilação EntLib ou qualquer coisa assim.

Em vez de simplesmente usar Logger.Write () eu fiz o seguinte: a) Criar o escritor log, usando o arquivo de configuração do dll:

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

b) Em seguida, use este escritor log dentro de seu código:

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

Aqui está o código completo para um objeto de amostra que eu criei. As referências foram 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;
        }
    }

}

O projeto incluiu um arquivo COMThing.dll.config que eu definir 'Copy to Output Directory' para 'Copiar sempre'. Esta é uma configuração trivial que grava informações de log para o log de eventos do aplicativo. O conteúdo do arquivo de configuração são:

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

Nas propriedades do projeto sob controle Construir 'Registar para interoperabilidade'. Construir o projeto, em seguida, criar o seguinte arquivo .vbs:

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

Se você clicar duas vezes este arquivo de vbs ele deve mostrar uma caixa de mensagem com o texto 'chamado a partir com pelo vbs' e escrever uma entrada para a sua aplicação Registro de Evento. Isso demonstra que enquanto o processo de execução é C:. \ WINDOWS \ System32 \ WScript.exe (ou similar), é obter a configuração do arquivo de configuração do seu dll

Eu baseei este na informação aqui em 'Usando Vários ConfigurationSources'.

Note que a classe Logger inclui lotes de métodos auxiliares agradáveis ??com argumentos diferentes. Desde que nós estamos usando a classe LogWriter nós não temos essa magia. Pessoalmente, eu vou ser a criação de uma outra classe dentro de minha biblioteca para executar o mesmo trabalho, com base em Logger.

O artigo mostra referenciados o mesmo princípio aplicado ao banco de dados e aplicação de exceção blocos. Presumivelmente o mesmo modelo pode ser aplicado a mais / todos eles.

Outras dicas

Verifique a questão relacionada que eu havia enfrentado. Talvez seja de alguma ajuda.

Como incluir componentes COM em um publicado. site net?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top