Entlib和互操作性:它有效吗,配置文件在哪里? [英] Entlib and interop: does it work, and where does the config file go?

查看:74
本文介绍了Entlib和互操作性:它有效吗,配置文件在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将.net代码中的EntLib 3.1用于注册了COM互操作的dll。我在哪里放置配置文件?

I'm trying to use the EntLib 3.1 within .net code for a dll which is registered for COM interop. Where do I put the config file?

或者,是否可以在dll代码中指定从中获取entlib配置的位置?因为我的dll将通过COM调用,所以我并不总是知道哪个exe会调用它。

Alternatively, is there a way to specify within the dll code where it should get the entlib config from? Since my dll will be called from COM I don't always know what exe will be calling it.

我创建了一个使用entlib Logging的简单应用,其中包含两个类: CallingApp和 MyComThing。当我从CallingApp调用MyComThing方法时,它会使用CallingApp的配置文件中的配置记录日志。当我从vbs脚本(即通过COM)调用MyComThing的方法时,出现错误在配置源中找不到用于日志记录的配置部分。我的COMThing.dll.config文件与已注册的COMThing.dll在同一文件夹中,即在bin\debug\文件夹中。

I created a simple app which uses entlib Logging, with two classes: 'CallingApp' and 'MyComThing'. When I call a method of MyComThing from CallingApp it logs using the configuration in CallingApp's config file. When I call the method of MyComThing from a vbs script, ie through COM, I get an error "The configuration section for Logging cannot be found in the configuration source". My COMThing.dll.config file is in the same folder as the registered COMThing.dll, ie in the bin\debug\ folder.

谢谢!

推荐答案

答案是企业库默认情况下使用exe的配置文件。如果您要生成一个包括COM在内的dll,则出于充分的原因,您可能不希望依赖于调用可执行文件。一种解决方案(可能有其他解决方案)是自己创建企业库对象,而不是使用默认对象,并告诉他们从何处获取配置。这并没有看上去那么可怕,并且不需要重新编译entlib或类似的东西。

The answer is that Enterprise Library by default uses the exe's config file. If you're producing a dll, including COM, then for good reason you might not want to depend on the calling executable. One solution to this (there might be others) is to create the Enterprise Library objects yourself instead of using the default ones, and tell them where to get the configuration from. This isn't as scary as it seems and doesn't require recompiling entlib or anything like that.

我做了以下工作,而不是简单地使用Logger.Write():
a)使用dll的配置文件创建日志写入器:

Instead of simply using Logger.Write() I did the following: a) Create the log writer, using the dll's config file:

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

b)然后在您的代码中使用此日志编写器:

b) Then use this log writer within your code:

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

以下是我创建的示例对象的完整代码。引用是Microsoft.Practices.EnterpriseLibrary.Common,Microsoft.Practices.EnterpriseLibrary.Logging,Microsoft.Practices.ObjectBuilder,System,System.Data,System.Windows.Forms,System.Xml:

Here's the full code for a sample object I created. The references were Microsoft.Practices.EnterpriseLibrary.Common, Microsoft.Practices.EnterpriseLibrary.Logging, Microsoft.Practices.ObjectBuilder, System, 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;
        }
    }

}

项目包括一个COMThing.dll.config文件,我将复制到输出目录设置为总是复制。这是一个简单的配置,它将日志信息写入应用程序事件日志。配置文件的内容为:

The project included a COMThing.dll.config file which i set 'Copy to Output Directory' to 'Copy always'. This is a trivial config that writes log information to the Application Event Log. The contents of the config file are:

<?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文件:

In the project properties under Build check 'Register for COM interop'. Build the project, then create the following .vbs file:

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

如果双击此vbs文件它应该显示一个消息框,其内容为 vbs从com调用com,并在应用程序事件日志中写入一个条目。这说明虽然执行过程是C:\WINDOWS\System32\WScript.exe(或类似文件),但它是从dll的配置文件中获取配置的。

If you double-click this vbs file it should show a message box with the text 'called from com by vbs' and write an entry to your Application Event Log. This demonstrates that while the executing process is C:\WINDOWS\System32\WScript.exe (or similar), it's getting the config from your dll's config file.

我基于此处使用多个ConfigurationSources。

I based this on the information here under 'Using Several ConfigurationSources'.

请注意,Logger类包含许多带有不同参数的漂亮助手方法。由于我们使用的是LogWriter类,因此无法获得这种魔力。我个人将基于Logger在我的库中创建另一个类来执行相同的工作。

Note that the Logger class includes lots of nice helper methods with different arguments. Since we're using the LogWriter class we don't get this magic. Personally I'll be creating another class within my library to perform the same job, based on Logger.

该参考文章显示了应用于数据库和异常应用程序块的相同原理。 。大概相同的模型可以应用于大多数/全部。

The referenced article shows the same principle applied to Database and Exception application blocks. Presumably the same model can be applied to most/all of them.

这篇关于Entlib和互操作性:它有效吗,配置文件在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆