9

Autofac を使用して RavenDB を登録する方法を教えてもらえますか?

builder.Register<DocumentStore>(..その後は?

4

1 に答える 1

15

以下は、ドキュメント ストアを接続する方法だけでなく、ドキュメント セッションをインジェクトでき​​るようにセットアップする方法も示すサンプル コンソール プログラムです。

using System.Threading.Tasks;
using Autofac;
using Raven.Client;
using Raven.Client.Document;

namespace ConsoleApplication1
{
  internal class Program
  {
    private static void Main()
    {
      var builder = new ContainerBuilder();

      // Register the document store as single instance,
      // initializing it on first use.
      builder.Register(x =>
        {
          var store = new DocumentStore { Url = "http://localhost:8080" };
          store.Initialize();
          return store;
        })
           .As<IDocumentStore>()
           .SingleInstance();

      // Register the session, opening a new session per lifetime scope.
      builder.Register(x => x.Resolve<IDocumentStore>().OpenSession())
           .As<IDocumentSession>()
           .InstancePerLifetimeScope()
           .OnRelease(x =>
             {
               // When the scope is released, save changes
               //  before disposing the session.
               x.SaveChanges();
               x.Dispose();
             });

      // Register other services as you see fit
      builder.RegisterType<OrderService>().As<IOrderService>();

      var container = builder.Build();


      // Simulate some activity.  5 users are placing orders simultaneously.
      Parallel.For(0, 5, i =>
        {
          // Each user gets their own scope.  In the real world this would be
          // a new inbound call, such as a web request, and you would let an
          // autofac plugin create the scope rather than creating it manually.
          using (var scope = container.BeginLifetimeScope())
          {
            // Let's do it.  Again, in the real world you would just inject
            // your service to something already wired up, like an MVC
            // controller.  Here, we will resolve the service manually.
            var orderService = scope.Resolve<IOrderService>();
            orderService.PlaceOrder();
          }
        });
    }
  }

  // Define the order service
  public interface IOrderService
  {
    void PlaceOrder();
  }

  public class OrderService : IOrderService
  {
    private readonly IDocumentSession _session;

    // Note how the session is being constructor injected
    public OrderService(IDocumentSession session)
    {
      _session = session;
    }

    public void PlaceOrder()
    {
      _session.Store(new Order { Description = "Stuff", Total = 100.00m });

      // we don't have to call .SaveChanges() here because we are doing it
      // globally for the lifetime scope of the session.
    }
  }

  // Just a sample of something to save into raven.
  public class Order
  {
    public string Id { get; set; }
    public string Description { get; set; }
    public decimal Total { get; set; }
  }
}

DocumentStore は単一のインスタンスですが、DocumentSession はライフタイム スコープごとのインスタンスであることに注意してください。このサンプルでは、​​ライフタイム スコープを手動で作成して並行して実行し、5 人の異なるユーザーが同時に注文を行う方法をシミュレートしています。彼らはそれぞれ独自のセッションを取得します。

OnRelease イベントへの SaveChanges の配置はオプションですが、すべてのサービスに配置する必要がなくなります。

現実の世界では、これは Web アプリケーションまたはサービス バス アプリケーションである可能性があり、その場合、セッションはそれぞれ単一の Web 要求またはメッセージの有効期間のいずれかにスコープする必要があります。

ASP.Net WebApi を使用している場合は、NuGet から Autofac.WebApi パッケージを取得し、.InstancePerApiRequest() メソッドを使用して、適切な有効期間スコープを自動的に作成する必要があります。

于 2012-11-08T00:13:37.763 に答える