13

ThreadContextでカスタムプロパティを簡単に確立できるようにするために、log4netロギングオブジェクトを初期化するためのラッパークラスを作成しました。これは、他の多くの便利な関数とともに確立したクラスライブラリ内で発生します。さまざまなライブラリのすべてに参加するために、「/internalize」スイッチを使用してAfterBuildターゲットをILMergeに追加しました。

ILMergeの対象となるライブラリ内のこの初期化子メソッドへのすべての参照は、正常に機能しているようです。ただし、このマージされたライブラリを他の場所で参照すると。私の実装は保護レベルのエラーをスローします。オプションのexclude(/internalize:excludes.txt)ファイルにさまざまなものを追加しようとしましたが、これは機能しないようです。

例excludes.txt:

log4net.Config
log4net.ThreadContext
log4net.LogManager

他の誰かがこの問題を抱えていましたか?

[編集]:

コードは次のとおりです。

 [assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Logging
{
    public static class Log4NetThreadContext
    {
        public static ILog Initialize(Type declaringType)
        {
            // Read from configuration
            XmlConfigurator.Configure();

            // Set Properties
            ThreadContext.Properties["ID"] = ...
                ...
                ...
                ...

            if(System.Diagnostics.Debugger.IsAttached)
            {
                // Special debugging logger
                return LogManager.GetLogger("DEBUG_MODE");
            }
            else
            {
                // Root logger
                return LogManager.GetLogger(declaringType);
            }
        }
    }
}

私はこのコードをそのように利用しています。

private static readonly Type declaringType = 
    MethodBase.GetCurrentMethod().DeclaringType;
private static readonly ILog log =
    Log4NetThreadContext.Initialize(declaringType);
...
log.Info("Something useful");

[編集]:

これは私のAfterBuildターゲットです

<Target Name="AfterBuild">
<CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
  <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
</CreateItem>
<Message Text="MERGING: @(AssembliesToMerge->'%(Filename)')" Importance="High" />
<Exec Command="&quot;$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe&quot; /targetplatform:v2 /log /internalize:&quot;ilmerge.excludes.txt&quot; /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
<Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />

保護レベルの問題をデバッグするための一般的なより良い方法はありますか?

Log4NetThreadContext.Initialize(System.Type)' is inaccessible due to its protection level
4

2 に答える 2

7

最終的に最も簡単な方法は、log4netをilmergeプロセスから完全に除外し、依存アセンブリとして維持することです。

それで、多くの拷問の後、ここに「それほど明白ではない」解決策があります。

結局、除外は必要ありませんでした。本当の答えは/lib:[path]、ilmergeでスイッチを使用することです。

ターゲットを更新して、スイッチAfterBuildから除外を削除しました。/internalize次に/lib、依存参照としてlog4netdllの場所を渡すスイッチを追加しました。次のようになります。

<Target Name="AfterBuild">
  <CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
    <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
  </CreateItem>
  <Message Text="MERGING: @(AssembliesToMerge->'%(Filename)')" Importance="High" />
  <Exec Command="&quot;$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe&quot; /lib:..\packages\log4net.2.0.0\lib\net35-full\ /targetplatform:v2 /log /internalize /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
  <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

<ILMerge />さらに、.csprojファイルにある参照に一意の要素を追加することにより、マージに含まれるアセンブリのリストを制限する別のターゲットを追加しました

<Target Name="AfterResolveReferences">
  <Message Text="Filtering out ILMerge assemblies from ReferenceCopyLocalPaths..." Importance="High" />
  <ItemGroup>
    <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.ILMerge)'=='false'" />
  </ItemGroup>
</Target>

したがって、参照要素は次のようにリストされています。

...
<Reference Include="Ionic.Zip">
  <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
  <ILMerge>True</ILMerge>
</Reference>
<Reference Include="log4net">
  <HintPath>..\packages\log4net.2.0.0\lib\net35-full\log4net.dll</HintPath>
  <ILMerge>False</ILMerge>
...

ILMerge = False値を/libスイッチに明示的に追加するためのより良い(プログラムによる)代替手段がおそらくありますが、私の場合、除外される項目が1つしかないため、これで十分です。それ以外の場合は、手動でパスを追加する必要があります。

私がリストした「AfterResolveReferences」テクニックのクレジットはhttp://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspxに行きます

うまくいけば、これは誰かを助けます!

于 2013-01-31T20:48:04.287 に答える
1

これは通常、リモートの場所からコードを実行しているときに発生します。.NETには、リモートの場所から構成ファイルにアクセスするときにアクセス許可の問題があります。たとえば、ネットワーク共有でのコードリポジトリの設定。

私は自分のコードをローカルハードドライブに移動することによってのみそれを克服することができました(ネットワーク共有のセキュリティを「信頼できる」などに上げるための管理者権限がないため)。

(これは主に、2005年より前のバージョンのVisual Studioの問題であることに注意してください。これは2008年以降に修正されたと思うので、影響がない可能性があります。ただし、使用しているバージョンはわかりません。)

于 2013-01-22T15:59:33.303 に答える