我正在尝试在.net代码中使用EntLib 3.1来为一个为COM互操作注册的dll。我在哪里放置配置文件?
或者,有没有办法在dll代码中指定它应该从哪里获取entlib配置?由于我的dll将从COM调用,所以我并不总是知道exe会调用它。
我创建了一个使用entlib Logging的简单应用程序,它有两个类:'CallingApp'和'MyComThing'。当我从CallingApp调用MyComThing方法时,它使用CallingApp的配置文件中的配置进行记录。当我从vbs脚本(即通过COM)调用MyComThing方法时,出现错误“无法在配置源中找到用于记录的配置部分”。我的COMThing.dll.config文件与注册的COMThing.dll位于同一文件夹中,即位于bin \ debug \文件夹中。
谢谢!
答案 0 :(得分:3)
答案是Enterprise Library默认使用exe的配置文件。如果你正在生成一个dll,包括COM,那么你可能不想依赖于调用可执行文件。对此(可能还有其他)的一个解决方案是自己创建企业库对象而不是使用默认对象,并告诉他们从哪里获取配置。这并不像看起来那么可怕,也不需要重新编译entlib或类似的东西。
我没有简单地使用Logger.Write(),而是执行了以下操作: a)使用dll的配置文件创建日志编写器:
string dllConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
FileConfigurationSource exceptionsSource = new FileConfigurationSource(dllConfigFilename);
LogWriterFactory writerFactory = new LogWriterFactory(exceptionsSource);
logWriter = writerFactory.Create();
b)然后在代码中使用此日志编写器:
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:
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}
Message: {message}
Category: {category}
Priority: {priority}
EventId: {eventid}
Severity: {severity}
Title:{title}
Machine: {machine}
Application Domain: {appDomain}
Process Id: {processId}
Process Name: {processName}
Win32 Thread Id: {win32ThreadId}
Thread Name: {threadName}
Extended Properties: {dictionary({key} - {value}
)}"
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 & Warnings">
<listeners>
<add name="Formatted EventLog TraceListener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
</configuration>
在Build check'Register for COM interop'下的项目属性中。构建项目,然后创建以下.vbs文件:
Set obj = CreateObject("COMThing.MyComThing")
obj.ProcessMessage("called from com by vbs")
如果双击此vbs文件,它应显示一个消息框,其中包含“由vbs从com调用”的文本,并在应用程序事件日志中写入一个条目。这表明虽然执行过程是C:\ WINDOWS \ System32 \ WScript.exe(或类似),但它从你的dll的配置文件中获取配置。
我的基础是“使用多个配置源”下的信息here。
请注意,Logger类包含许多带有不同参数的好助手方法。由于我们使用的是LogWriter类,因此我们无法获得这种魔力。就个人而言,我将在我的库中创建另一个类来执行相同的工作,基于Logger。
引用的文章显示了应用于Database和Exception应用程序块的相同原则。据推测,相同的模型可以应用于大多数/所有模型。
答案 1 :(得分:0)
检查我遇到的相关问题。也许它有一些帮助。