OK、これは可能ですが、きれいではありません...
まず第一に、このシナリオでは「メイン」や「アプリケーションの開始」などではないため、アセンブリがロードされたときにフックする方法が必要です。AppDomain にはAssemblyLoadedと呼ばれる興味深いイベントがあり、うまくいくように見えますが、それにフックする方法は、カスタム アプリ ドメイン マネージャーを定義することです。
新しいアセンブリを作成し、その中にインターフェイスを定義します。これは、次のように一部のクライアントとAppDomainManagerによって実装できます。
public interface IAssemblyLoaded
{
void AssemblyLoaded();
}
public class CustomManager : AppDomainManager
{
public override void InitializeNewDomain(AppDomainSetup appDomainInfo)
{
base.InitializeNewDomain(appDomainInfo);
// Look for any classes that implement IAssemblyLoaded,
// constuct them (will only work if they have a default constructor)
// and call the AssemblyLoaded method
var loaded = typeof (IAssemblyLoaded);
AppDomain
.CurrentDomain
.AssemblyLoad += (s, a) =>
{
var handlers = a
.LoadedAssembly
.GetTypes()
.Where(loaded.IsAssignableFrom);
foreach (var h in handlers)
{
((IAssemblyLoaded)
Activator.CreateInstance(h))
.AssemblyLoaded();
}
};
}
}
アセンブリが署名されていることを確認してから、GAC に追加します。アセンブリAssemblyInitCustomDomainManagerを呼び出したとしましょう。次のように追加できます(必要になるため、すぐに詳細を取得できます)。
gacutil /i AssemblyInitCustomDomainManager.dll
gacutil /l AssemblyInitCustomDomainManager
ここで、WcfServiceHost.exe.config (通常は次の場所にあります: C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE または 64 ビット システムの x86 バージョン) を編集し、ランタイム要素内に次を追加します (詳細については、こちらを参照してください)。この設定):
<appDomainManagerType value="AssemblyInitCustomDomainManager.CustomManager" />
<appDomainManagerAssembly value="AssemblyInitCustomDomainManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c841b3549556e52a, processorArchitecture=MSIL" />
注: 型名、名前空間、アセンブリ名、公開キー、バージョン番号の少なくとも 1 つ (および上記の名前によってはすべて) を変更する必要があります。あなたの場合、彼らが何をする必要があるかを理解できるはずです。
OK、これは簡単でした。Visual Studio で新しい「WCF Service Library」プロジェクトを作成すると、app.config とサービスが作成されます (これは、テストしたいプロジェクトの種類です。そう願っています!)。
まず、サービス ホスト アプリケーションにこれを読み取らせたくないため、app.config からsystem.servicemodel部分を削除します。次に、Service1.cs と IService1.cs を削除します (独自のものを少し作成するため)。後で)。そのインターフェイスを実装する必要があるため、前に作成したアプリ ドメイン マネージャー アセンブリを必ず参照してください。
ここで、新しいファイルを作成し、次のコードを貼り付けます (Castle WCF ファシリティによってホストされる依存関係を持つ単純なサービスがあります)。
using System;
using System.ServiceModel;
using AssemblyInitCustomDomainManager;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using Castle.Windsor.Installer;
namespace TestWcfServiceLibrary
{
public class AssemblyInitializedHandler : IAssemblyLoaded
{
// This method is called when the assembly loads so we will create the
// windsor container and run all the installers we find
public void AssemblyLoaded()
{
new WindsorContainer().Install(FromAssembly.This());
}
}
// This installer will set up the services
public class ServicesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container,
IConfigurationStore store)
{
container
.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
.Register(Component
.For<ITestDependency>()
.ImplementedBy<TestDependency>(),
Component
.For<IService1>()
.ImplementedBy<Service1>()
.AsWcfService(new DefaultServiceModel(WcfEndpoint
.BoundTo(new WSHttpBinding()))
.AddBaseAddresses("http://localhost:9777/TestWcfServiceLibrary/Service1")
.PublishMetadata(m => m.EnableHttpGet())));
}
}
// This is the contract of something we want to make sure is loaded
// by Windsor
public interface ITestDependency
{
int DoSomething(int value);
}
public class TestDependency : ITestDependency
{
public int DoSomething(int value)
{
return value;
}
}
// Regular WCF service contract
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
// Service implementation - notice it does not have a default
// constructor
public class Service1 : IService1
{
private readonly ITestDependency _td;
public Service1(ITestDependency td)
{
_td = td;
}
public string GetData(int value)
{
int v = _td.DoSomething(value);
return string.Format(
"According to our dependency you entered: {0}", v);
}
}
}
[実行] をクリックすると、次のようなエラー メッセージが表示されます。
WCF サービス ホストは、サービス メタデータを見つけることができません。これにより、クライアント アプリケーションが正しく実行されない可能性があります。メタデータが有効になっているかどうかを確認してください。終了しますか?
いいえをクリックしてください。
テスト クライアントが起動しますが、残念ながらサービスが含まれていません。add service... を右クリックしてサービスの URL を入力するだけです (コードのインストーラーにある - http://localhost:9777/TestWcfServiceLibrary/Service1 )。
では、WCF テスト クライアント内でホストされる WCF サービスについて説明します。信じないでください。テストして GetData 操作を呼び出すと、結果が表示されるはずです。
ほらね。これが良いアイデアかどうか尋ねた場合...わかりませんが、機能し、あなたが求めていたものだと思います...