編集:私はこれを読み違えて、autofac を使用して依存関係を登録する方法についての質問だと思いました。同じ UnitOfWork を維持したい場合は、インスタンスの有効期間を何かに限定する必要があります。これを ASP.NET または WCF アプリケーションで使用している場合は、次のように依存関係を登録できます。
typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
Autofac のようなコンテナーを使用するために必要な最初のことは、すべての依存関係を登録することです。Autofac ではいくつかの方法でそれを行うことができますが、それらはすべて a の使用に依存していContainerBuilder
ます。はContainerBuilder
拡張メソッドに依存しているusing
ため、Autofac 名前空間のステートメントがあることを確認してください。
ファクトリ メソッドを明示的に定義できます。
// Explicitly
var builder = new ContainerBuilder();
builder.Register<UnitOfWork>(b => new UnitOfWork());
builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>()));
builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>()));
ContainerBuilder を使用してRegister<>()
、サービス インターフェイスを提供するメソッドにアクセスします (これは、コンテナーにサービスを要求する方法です)。この場合、インターフェイスは使用せず、実際の型だけを使用します。コンテナに を要求するたびにUnitOfWork
、ファクトリ メソッドを使用してコンテナnew UnitOfWork()
を生成します。実生活では、おそらくIUnitOfWork
. これはすべて少し冗長になる可能性がありますが、依存関係の作成にカスタム ロジックが必要な場合に非常に便利です。
他の依存関係コンテナーと同じようにビルダーを使用して、型を登録するだけです。
// Implicitly
var typeBuilder = new ContainerBuilder();
typeBuilder.RegisterType<UnitOfWork>();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
このアプローチは、クラスを構築するために必要なすべての依存関係を登録することに依存しています。その後、コンテナーはリフレクションを使用して、コンストラクターの引数を解決します。引数が登録されていない場合、コンテナーは解決できなかった型の例外をスローします。この場合、サービスは と に依存しUnitOfWork
ていRepository
ます。Repository
にも依存していUnitOfWork
ます。これらの依存関係は、コンストラクターの引数として表されます。Repository
コンテナからまたはをリクエストするにService
は、すべての依存関係を登録する必要があります
構成アプローチを使用できます。
app.config ファイルを使用している場合は、次のように構成ファイルを定義できます。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
<autofac defaultAssembly="AutoFacTest">
<components>
<component
type="AutoFacTest.Repository, AutoFacTest"
service="AutoFacTest.Repository" />
<component
type="AutoFacTest.UnitOfWork, AutoFacTest"
service="AutoFacTest.UnitOfWork" />
<component
type="AutoFacTest.Service, AutoFacTest"
service="AutoFacTest.Service" />
</components>
</autofac>
</configuration>
まず、構成セクションを定義する必要があることに注意してください ( に注意して<ConfigSections>
ください)。次に、<autofac>
すべての依存関係を定義するセクションを作成できます。表記法は非常に単純で、基本的に<component>
for every 依存関係を作成します。各コンポーネントには、service
要求されるタイプを定義する属性があります。type
サービスのインスタンスが要求されたときに作成されるオブジェクトを定義する属性もあります。これは、要求されたサービス (およびこの場合) が作成されるタイプにも似てbuilder.Register<UnitOfWork>(b => new UnitOfWork())
います。UnitOfWork
構成を使用してビルダーを作成するには、ConfigurationSettingsReader()
// Config
var configBuilder = new ContainerBuilder();
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac"));
構成セクションの名前 (この場合はautofac
) を渡す必要があります。依存関係を構成したら、コンテナーを構築する必要があります。にContainerBuilder
は、これを行うメソッドが含まれています。
var container = builder.Build();
var typeContainer = typeBuilder.Build();
var configContainer = configBuilder.Build();
コンテナを取得したら、サービスのインスタンスをリクエストできます。
container.Resolve<Service>().DoAwesomeness();
typeContainer.Resolve<Service>().DoAwesomeness();
configContainer.Resolve<Service>().DoAwesomeness();
完全なプログラム:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;
using Autofac.Configuration;
namespace AutoFacTest
{
class Program
{
static void Main(string[] args)
{
// Explicitly
var builder = new ContainerBuilder();
builder.Register<UnitOfWork>(b => new UnitOfWork());
builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>()));
builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>()));
// Implicitly
var typeBuilder = new ContainerBuilder();
typeBuilder.RegisterType<UnitOfWork>();
typeBuilder.RegisterType<Repository>();
typeBuilder.RegisterType<Service>();
// Config
var configBuilder = new ContainerBuilder();
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac"));
var container = builder.Build();
var typeContainer = typeBuilder.Build();
var configContainer = configBuilder.Build();
container.Resolve<Service>().DoAwesomeness();
typeContainer.Resolve<Service>().DoAwesomeness();
configContainer.Resolve<Service>().DoAwesomeness();
Console.Read();
}
}
public class Repository
{
private readonly UnitOfWork _unitOfWork;
public Repository(UnitOfWork uow)
{
_unitOfWork = uow;
}
public void PrintStuff(string text)
{
Console.WriteLine(text);
}
}
public class Service
{
private readonly Repository _repository;
private readonly UnitOfWork _unitOfWork;
public Service(Repository repo, UnitOfWork uow)
{
_repository = repo;
_unitOfWork = uow;
}
public void DoAwesomeness()
{
_repository.PrintStuff("Did awesome stuff!");
_unitOfWork.Commit();
}
}
public class UnitOfWork
{
public bool Commit()
{
return true;
}
}
}