アセンブリを Windows サービス (ala NServiceBus) としてホストできるようにする非常に単純な汎用ホスト ソリューションを開発しています。次の例外に出くわしています (Dru のブログ投稿で言及されているコメントと同様)。さまざまな AppDomains でサービスをホストできるように、これが機能する必要があります。
「アセンブリ 'MyProject.WindowsServices.GenericHost.Program+<>c__DisplayClass5' と入力 'MyProject.WindowsServices.GenericHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' はシリアル化可能としてマークされていません。」
私は、topshelf ホームページ (topshelf-project.com) のダウンロード リンクから入手できる Topshelf 1.0 RC バイナリを使用しています。最新のビルド (2010 年 7 月 29 日) を試してみました。ビルドは Google コードと github からダウンロードできます。私はそれらのどれも私のために働かせることができません!
これは、古いバージョンの Topshelf (dll のバージョンは 0.8.0.96) の NServiceBus ライブラリで機能しています。以下に示すコードに若干の変更を加えることで (HowToBuildService の代わりに CreateServiceLocator を使用)、これらの古いバイナリでも機能しますが、計画されている修正や機能強化を利用するために、最新のコードに固執したいと思います。
これが私のコードです。
static void Main(string[] args)
{
ArgumentParser arguments = new ArgumentParser(args);
string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
arguments.ServiceType.Assembly.ManifestModule.Name + ".config");
RunConfiguration cfg = RunnerConfigurator.New(x =>
{
x.SetServiceName(arguments.ServiceName);
x.SetDisplayName(arguments.DisplayName);
x.SetDescription(arguments.Description);
if (string.IsNullOrEmpty(arguments.UserName))
{
x.RunAsLocalSystem();
}
else
{
x.RunAs(arguments.UserName, arguments.Password);
}
x.ConfigureServiceInIsolation<GenericHost>(c =>
{
c.ConfigurationFile(configFile);
c.Named(arguments.ServiceType.AssemblyQualifiedName);
c.HowToBuildService(name => new GenericHost(arguments.ServiceType));
c.WhenStarted(tc => tc.Start());
c.WhenStopped(tc => tc.Stop());
});
});
Runner.Host(cfg, args);
}
また、GenericHost クラスと、arguments.ServiceType で識別されるクラスは両方とも MarshalByRefObject を実装しており、これらのクラスを Serializable にして、それが役立つかどうかを確認していることにも注意してください。問題を引き起こしているのはこれらのクラスではありませんが、構成したラムダの 1 つ以上に対して C# コンパイラによって生成された匿名型について不平を言っているようです。
ConfigureServiceInIsolation() を使用してこの問題が発生している人はいますか? そうでない場合、ここで何が欠けているか知っている人はいますか? スタック トレースやその他のコードなど、さらに情報が必要な場合はお知らせください。