0

Autofac を IOC コンテナーとして使用している Windows サービス プロジェクトがあります。このサービスは Exchange サーバーからのメールを「スニッフィング」しているため、Exchange サーバーで何らかのイベントが発生するたびに、Windows サービスはその新しいアイテムを Exchange サーバー以外の場所にコピーする必要があるかどうかを確認します。

すべてのイベント ハッピング (メール送信、メール受信、新しいタスクなど) に対して、ログに使用できる一意のセッション ID が必要です。そうすれば、(NLog を使用して) ログ内の Exchange サーバー イベントを追跡することが容易になります。

私は次のことを試しましたが、毎回新しい GUID を取得します。セッション/Exchange サーバー イベントごとに新しい GUID のみが必要です。

autofac セットアップ クラス (bootstrapper.cs) で

builder.RegisterType<SessionService>().As<ISessionService>()
    .InstancePerLifetimeScope();

私もこれで試しましたが、同じ結果:

builder.RegisterType<SessionService>().As<ISessionService>()

私のセッションサービスの実装:

public class SessionService : ISessionService
{
    private readonly Guid _sessionGuid;

    public SessionService()
    {
        _sessionGuid = Guid.NewGuid();
    }

    public Guid GetNewSessionGuid()
    {
        return _sessionGuid;
    }
}

次に、たとえば、交換サーバーイベントから他のシステムに情報を保存しようとするときに、何かをログに記録する必要があります。単なる情報である場合もあれば、エラーである場合もあります。どちらにしても、イベントと同じ GUID である必要があります。

たとえば、私のPushNotificationListenerクラスでは、プロパティ注入を使用します。

public ILogger Logger
{
    get
    {
        using (var scope = IocContainer.Container.BeginLifetimeScope())
        {
            return scope.Resolve<ILogger>();
        }
    }
}

public ILogFormater LogFormater
{
    get
    {
        using (var scope = IocContainer.Container.BeginLifetimeScope())
        {
            return scope.Resolve<ILogFormater>();
        }
    }
}

public ISessionService SessionService
{
    get
    {
        using (var scope = IocContainer.Container.BeginLifetimeScope())
        {
            return IocContainer.Container.Resolve<ISessionService>();
        }
    }
}

次に、次のように GUID の sessionservice を呼び出します。

Logger.LogInfo(LogFormater.EventLogFormat(
    SessionService.GetNewSessionGuid(),
    exchangeEventType.ToString(),
    message.Notification.ItemsElementName[count].ToString(),
    _service.ImpersonatedUserId.Id,
    mailEvent.TimeStamp));

私の MailService クラスでは、最初にコンストラクターがあるため、依存関係の挿入を確認できます。

public MailService(
    ILogger logger,
    ILogFormater logFormater,
    ISessionService sessionService)
{
    _logger = logger;
    _logFormater = logFormater;
    _sessionService = sessionService;
}

そして、たとえば新しいメールが別のシステムに保存されている場合、i はセッション GUID を呼び出します。

_logger.LogInfo(_sessionService.GetNewSessionGuid().ToString());

PushNotificationListener クラスと MailService クラスで _sessionService.GetNewSessionGuid() メソッドを呼び出すと、2 つの異なる GUID が得られます。

それらを同じガイドにしたい。それ、どうやったら出来るの?

4

1 に答える 1

0

この問題は、PushNotificationListenerクラスのプロパティが原因で発生します。その中に新しいライフタイム スコープを作成するため、そのスコープ内に新しいSessionServiceが作成されます。これを防止します。

代わりに、セッションごとに有効期間スコープを 1 つだけにする必要があります。イベントが発生した直後で、ルート オブジェクトを解決する前に、新しい有効期間スコープ (および 1 つの有効期間スコープのみ) を作成する必要があります。その時点から、コンストラクター注入を使用してすべての依存関係を注入する必要があります。これにより、そのスコープ内に が 1 つだけ存在することが保証されますSessionService

于 2013-08-07T07:34:10.603 に答える