スコープ付きの有効期間で解決したいサービスがあるとします。しかし、いつか私はそれをインターフェースタイプとして、そして時には実装タイプとして解決しようとします。ASP.NETコアDI:スコープ付きサービスがサービスタイプと実装タイプの両方として登録されている場合、同じインスタンスを解決する
私がしようとした最初の事はだったこの:
ServiceCollection services;
services.AddScoped<MyClass>();
services.AddScoped<IMyInterface, MyClass>();
上記のサンプルでの問題、私はIMyInterfaceという解決し、よりMyClassのを解決する場合は、別のインスタンスが使用されていることです。基本的に、2つの有効範囲のインスタンスが同時に存在する可能性があります。
この問題を回避するには、次の方法があります。しかし、これは非常に誤りがちです。なぜなら、これを1か所で簡単に忘れることができるからです。気づくのは本当に難しいです。
serviceCollection.AddScoped<MyClass>();
serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());
エラーが発生しにくい方法で目的を達成する方法はありますか?好ましくは、必ずしもそうではないが、単一登録で好ましいか?
I.e. xUnitのテストとして:
public class Tests
{
[Fact]
public void ReturnsSameInstanceForImplementationAndServiceType()
{
var serviceCollection = new ServiceCollection();
// TODO: Change these lines so they're less error prone.
serviceCollection.AddScoped<MyClass>();
serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());
var services = serviceCollection.BuildServiceProvider();
var myInt = services.GetRequiredService<IMyInterface>();
var myCls = services.GetRequiredService<MyClass>();
Assert.Equal(myCls, myInt);
}
class MyClass : IMyInterface { }
interface IMyInterface { }
}
なぜ実装を登録するのですか? –
@CamiloTerevinto私はそれがベストプラクティスではないことに同意しますが。私は実装が多くの場所で注入されている、古いコードベースの種類のもので動作します。現時点ではこれをインタフェースに変更することはできません。 –