2011-03-01 18 views
6

私はIoCとDIで苦労している初心者です。私は、autofac(またはその他の適切な.NET IoCツール)を使用して、接続と接続ファクトリを動的に解決できるようにしたいと考えています。IoC、工場とコンストラクタの引数

シナリオは

Iは以下のコードとDIとのIoCを適用すると、I等の接続ファクトリコンストラクタでnamedParameterの混乱を取得するなどのトレースのためのより多くの設備を備えた別のものへの接続の実装を変更することができます一意のポートを持つ新しい接続を返します(愚かな例ですが、私は工場で何らかの状態を保つ必要があることを示しています)

私はIPとポート範囲に対してプロパティインジェクションを使うことができました。コネクションにコンストラクタのポイントであるIPまたはポートがあることは保証されません。 また、指定されたパラメータによって、引数の名前にも依存しています。

アイデア、パターン、IoCポインタが高く評価されています。

更新:

、より具体的に:どのように私は、注射する接続クラスを変えることができますか?私はプロパティインジェクションと一緒に行くべきですか?または、私ができるトリックは、コンストラクターの引数を使ってより安全な解決を得ることができますか?今

public interface IConnection { 
    void Open(); 
    void Close(); 
    string Execute(string command); 
} 

public interface IConnectionFactory { 
    IConnection CreateConnection(); 
} 

public class Connection : IConnection { 
    ... 
    public Connection(String ip, int port) { 
    _ip = ip; 
    _port = port; 
    } 

    public string Execute() {} 
    public void Open() {} 
    public void Close() {} 
} 


public class ConnectionFactory : IConnectionFactory { 
    //How would I resolve this? 
    public ConnectionFactory(string ip, int fromPort) { 
     ... 
    } 
    public IConnection CreateConnection() { 
     //How would I resolve this? 
     return new Connection(ip, fromPort++); 
    } 
} 

、用法:

//Register 
builder.RegisterType<Connection>().As<IConnection>(); 
builder.RegisterType<ConnectionFactory>().As<IConnectionFactory>().SingleInstance(); 
... 

var connection = container.Resolve<IConnectionFactory>(
     new NamedParameter("ip", "127.0.0.1"), 
     new NamedParameter("fromPort", 80).CreateConnection()); 
+0

上記のコードで実際の質問/問題を明確にしたい場合や、特定のIoCフレームワークのドキュメンテーションリンク/サンプルの直後であるかどうかを明確にすることができます。 – Reddog

+0

コメントありがとう、私はより具体的にしようとしました! – Larsbj

+0

私はプロパティインジェクションに進み、最初にオブジェクトを解決してプロパティを渡します。 – sajoshi

答えて

6

解決時にコンストラクタ引数を渡すする代わりに、登録機能にこれらの引数を符号化することである:それは接続ファクトリのインスタンスを作成する必要があるとき

builder 
.Register(c => new ConnectionFactory("127.0.0.1", 80)) 
.As<IConnectionFactory>() 
.SingleInstance(); 

Autofacは、その機能を使用します。

ConnectionFactorySingleInstanceと設定したので、それはIConnectionFactoryに依存するすべてのコンポーネントで共有されます。

builder 
.Register(c => new ConnectionFactory("192.168.0.1", 80)) 
.Named<IConnectionFactory>("AlernateConnectionFactory") 
.SingleInstance(); 
:あなたは一回限りと言う、異なるIPを使用して、 ConnectionFactory、あなたが名前の登録を使用することができている場合は

public class ConnectionFactory : IConnectionFactory 
{ 
    private int _fromPort; 

    public ConnectionFactory(string ip, int fromPort) 
    { 
     ... 
     _fromPort = fromPort; 
    } 

    public IConnection CreateConnection() 
    { 
     return new Connection(ip, _fromPort++); 
    } 
} 

:これはCreateConnectionへの呼び出しの間、自身の状態を維持するためにConnectionFactoryニーズを意味し、

あなたはコンポーネントがその特定工場の代わりに、デフォルトの1を使用したい場合は、あなたがResolveNamed methodを使用することができます。

builder.Register(c => new Foo(c.ResolvedNamed<IConnectionFactory>("AlernateConnectionFactory"))); 

これは、タイプを複数の方法で構成し、特定の場所で使用するのに便利なテクニックです。

+0

私はクラスの代わりにインスタンスを登録することを考えなかったとは思えません。コンセプトはとてもシンプルで、必要なものだけです。 *額を叩く*ありがとう! – Larsbj

+0

パラメタが定数でない場合はどうなりますか? – sebas

+0

@sebas:私は、一般に、これらの種類の登録をモジュールにまとめます。モジュールは、コンストラクターのURLやポートなどの構成パラメーターを受け入れ、それらを登録で使用します。特定のアプローチについては、この私の答えを参照してください:http://stackoverflow.com/questions/3587380/dependency-injection-and-appsettings/3592370#3592370 –

2

私はAutofacを経験していないのですが、私はユニティに非常によく似た問題を解決しました。ここでは、スニペットです:

私は、この(これはさえ設定ファイルで行うことができます)ような何か私のコンテナを設定する場合:

:後で

string connectionString = ConfigurationManager.ConnectionStrings["XYZ"].ConnectionString; 
Container.RegisterType<IConnection, Connection>(new PerThreadLifetimeManager(), 
               new InjectionConstructor(connectionString)); 

を、私は言って接続を構築することができます

IConnection myConnection = Container.Resolve<IConnection>(); 

または依存プロパティを指定:

[Dependency] 
IConnection Connection {get;set;} 

又はための注射パラメータとして

コンストラクタ・インジェクション:

[InjectionConstructor] 
public SomeClassThatUsesConnections(IConnection connection) 
{ ... } 

私は、私は2つのスレッドが接続を共有していないことを保証することでIOCの契約を聞かせていることを指摘してPerThreadLifetimeManagerを残しました。

質問のあなたのサンプルとの違いは微妙ですが、依存関係プロパティとして、または注入コンストラクタの一部として持つことができる各インスタンス化からパラメータを削除します。

希望に役立ちます。

+0

あなたの答え、もう一つの素晴らしいアイデアをありがとう。私はそのアプローチについて全く考えていませんでした。 – Larsbj

1

「AppConfigConnectionFactory」(またはWebConfig、DBConfigなど)を作成し、これらのプロパティーを構成を介して外部化する方法があります。私は決してDIフレームワークからすぐに構成データをロードすることを感じなかった。

+0

素晴らしいアイデア、ありがとう! – Larsbj

関連する問題