私の目標は、複数のアセンブリを解析し、コントラクトを検出し、サービスをホストできるホスト アプリケーションを作成することです。
サービスをロードするには、通常、サービスホストのインスタンス化をハードコーディングする必要があります。次のコードは、私が探している動作ではありませんが、機能しています。
ServiceHost wService1Host = new ServiceHost(typeof(Service1));
wService1Host.Open();
ServiceHost wService2Host = new ServiceHost(typeof(Service2));
wService2Host.Open();
ただし、これは、サービスがどうなるかを事前に知っていることを意味します。サービスを含むアセンブリへの参照があってもかまいません。アセンブリに含まれるサービスをホストに知られたくないだけです。たとえば、アセンブリの 1 つに新しいサービスを追加した場合、ホスト側で変更は必要ありません。
これはこの質問と非常によく似ていますが、上記の理由により複雑さが増しています。
ここに私がこれまでに持ってきたホストコードがあります。現時点では、サービスを管理することは気にしません。単に適切にロードされることを望んでいます。
class Program
{
static void Main(string[] args)
{
// find currently executing assembly
Assembly curr = Assembly.GetExecutingAssembly();
// get the directory where this app is running in
string currentLocation = Path.GetDirectoryName(curr.Location);
// find all assemblies inside that directory
string[] assemblies = Directory.GetFiles(currentLocation, "*.dll");
// enumerate over those assemblies
foreach (string assemblyName in assemblies)
{
// load assembly just for inspection
Assembly assemblyToInspect = Assembly.ReflectionOnlyLoadFrom(assemblyName);
// I've hardcoded the name of the assembly containing the services only to ease debugging
if (assemblyToInspect != null && assemblyToInspect.GetName().Name == "WcfServices")
{
// find all types
Type[] types = assemblyToInspect.GetTypes();
// enumerate types and determine if this assembly contains any types of interest
// you could e.g. put a "marker" interface on those (service implementation)
// types of interest, or you could use a specific naming convention (all types
// like "SomeThingOrAnotherService" - ending in "Service" - are your services)
// or some kind of a lookup table (e.g. the list of types you need to find from
// parsing the app.config file)
foreach (Type ty in types)
{
Assembly implementationAssembly = Assembly.GetAssembly(ty);
// When loading the type for the service, load it from the implementing assembly.
Type implementation = implementationAssembly.GetType(ty.FullName);
ServiceHost wServiceHost = new ServiceHost(implementation); // FAIL
wServiceHost.Open();
}
}
}
Console.WriteLine("Service are up and running.");
Console.WriteLine("Press <Enter> to stop services...");
Console.ReadLine();
}
}
serviceHost を作成しようとすると、次のエラーが発生します。
"It is illegal to reflect on the custom attributes of a Type loaded via ReflectionOnlyGetType (see Assembly.ReflectionOnly) -- use CustomAttributeData instead."
上記のリンクでは、公開したいサービスを事前に知っているため、その人は typeof を使用して問題を解決したようです。残念ながら、これは私の場合ではありません。
注:ホスティング部分については、実際には3つのプロジェクトがあります。1 つ目はホスト アプリケーション (上記を参照) で、2 つ目はすべてのサービスのコントラクト (インターフェイス) を含むアセンブリで、最後のアセンブリにはサービスの実装が含まれます。
サービスのホスティングに実際に使用する app.config を次に示します。実装を含むアセンブリは "WcfServices" という名前で、2 つのサービスが含まれています。1 つはコールバックを公開することで、もう 1 つは基本的なサービスのみを公開することです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfServices.Service1"
behaviorConfiguration="metadataBehavior">
<endpoint address="Service1Service"
binding="basicHttpBinding"
contract="WcfServices.IService1"
name="basicHttp"/>
<endpoint binding="mexHttpBinding"
contract="IMetadataExchange"
name="metadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Service1"/>
</baseAddresses>
</host>
</service>
<service name="WcfServices.Service2"
behaviorConfiguration="metadataBehavior">
<endpoint address="Service2Service"
binding="wsDualHttpBinding"
contract="WcfServices.IService2"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Service2"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
明確にするために、ここに私が探しているものがあります:
1.現在のアプリディレクトリにアセンブリをロードします
2.そこにコントラクトの実装があるかどうかを調べ
ます3.ある場合は、それらのサービスをインスタンス化します(今のところapp.configを使用) )
まず第一に、これは可能ですか?(私の推測では、wcfstorm という名前のアプリケーションが既にこれを行っているようです)
明らかに、上記のコードを機能させるにはどうすればよいでしょうか?
ありがとうございました!