1

IoCと依存性注入を学習しようとしています。そして、私はその原則とパターンを正しく理解したかどうか疑問に思っています。

UnitOfWork/リポジトリパターンを実装しようとしています。単体テスト用のリポジトリクラスの2つの実装が必要であり、UnitOfWorkがインスタンス化する具象実装を(Unityの助けを借りて)「決定」する必要があります。

IUserRepositoryインターフェイス

public interface IUserRepository
{
    List<User> getAll();       
}

実際のデータを使用したリポジトリの実装

public class UserRepository : IUserRepository
{

    private MyDbContext db;

    public UserRepository(MyDbContext db)
    {
        this.db = db;
    }

    public List<DomainModel.User> getAll()
    {
        return db.Users.ToList();
    }
}

FakeRepositoryの実装

public class FakeUserRepository : IUserRepository
{
    private List<User> userSet;

    public FakeUserRepository()
    {
        // Fake Data
        userSet = new List<User>();
        userSet.Add(new User { Username = "john", Active = true, EMail = "john@ann.net", Password = "supersecret" });
        userSet.Add(new User { Username = "ashley", Active = true, EMail = "ashley@ann.net", Password = "supersecret" });
        userSet.Add(new User { Username = "kaidan", Active = true, EMail = "kaidan@ann.net", Password = "supersecret" });
        userSet.Add(new User { Username = "tali", Active = true, EMail = "tali@ann.net", Password = "supersecret" });

    }

    public List<DomainModel.User> getAll()
    {
        return userSet;
    }

}

Unityを使用したUnitOfWorkの実装

// To Keep it simple, i skipped the IDisposable part ;)

public class UnitOfWork
{
    MyDbContext db;
    private IUserRepository userRepository;
    UnityContainer container = new UnityContainer();
    public UnitOfWork(bool fake = false)
    {
        if (fake)
        {
            container.RegisterType<IUserRepository, FakeUserRepository>();
        }
        else
        {
            db =  = new MyDbContext();
            container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor(db));
        }
    }


    public IUserRepository UserRepository
    {
        get
        {
            if (userRepository == null)
            {
                userRepository = container.Resolve<IUserRepository>();
            }
            return userRepository;
        }
    }

    public void Save()
    {
        db.SaveChanges();
    }
}

これで、呼び出すnew UnitOfWork()と「UnitOfWorkwithRealData」の実装が表示されます。電話new UnitOfWork(fake: true)すると「UnitOfWorkwithFakeData」が表示されます。ここまでは順調ですね。しかし、これはUnityとDIの使用方法ですか?アプリケーションが30個のリポジトリに成長した場合、大きな「If / else」ブロックを定義することになりますか?また、データのソースとしてXMLやWCFなどのデータストアを追加したいとします。上記のように使い続けると、非常に複雑で吹き飛ばされたUnitOfWorkクラスになってしまいます。

まず、DIとUnityを使用する必要があるので、理解したかどうかはわかりません。私がそれを正しく理解した場合:適切なタイプのUnitOfWorkを提供するファクトリを使用する方が良いでしょうか?

ヘルプやヒントは大歓迎です。

ありがとう、

マッツァー

4

1 に答える 1

1

リポジトリで行ったように、作業単位を分離します。IUnitOfWorkインターフェイスと、偽物およびEntityFramework作業単位の具象クラスです。現在の作業単位は、複数の責任があるため、単一責任の原則に違反しています。

  • save呼び出しをEntityFrameworkの作業単位に渡します
  • 作業単位が偽物であるか本物であるかを判断する
  • Unityコンテナへのリポジトリの登録

Entity Frameworkの作業単位が別にある場合は、リポジトリを解決するためのコンテナは必要ありませんが、コンストラクタで初期化するメンバー変数にすることができます。コンテナに正しい作業単位を登録するだけです。

于 2012-04-04T08:32:17.760 に答える