结构图 3 多重装饰

本文关键字:重装 结构图 | 更新日期: 2023-09-27 18:35:01

我正在尝试在 StructureMap 3 中创建一个带有装饰器链的依赖关系图:

每个实例都有一个具有多个 arugment 的构造函数,但恰好是一个内部 IGeocoder 的一个参数,例如

public SomeCachingGeocoder(IGeoCoder inner, IFoo somethingElse)

我像这样连接它们:

For<OviGeoCoder>().Use<OviGeoCoder>();
For<SqlCachingGeocoder>().Use<SqlCachingGeocoder>().Ctor<IGeoCoder>().Is<OviGeoCoder>();
For<RedisCachingGeocoder>().Use<RedisCachingGeocoder>().Ctor<IGeoCoder>().Is<SqlCachingGeocoder>();
For<IGeoCoder>().Use<RedisCachingGeocoder>();

但我得到

检测到双向依赖关系!检查下面的结构图堆栈跟踪:
1.( SOAM 的实例。Services.IGeoCoder (SOAM.Services.Geocoding.RedisCachingGeocoder(
2.( 新的 RedisCachingGeocoder(IDatabase 的默认值IGeoCoder 的默认值(
3.(SOAM。Services.Geocoding.RedisCachingGeocoder
4.( SOAM 的实例。Services.IGeoCoder (SOAM.Services.Geocoding.RedisCachingGeocoder(
5.( new HomeController(IGeoCoder的默认值IAlertService的默认值(
6.(SOAM。Web.Controllers.HomeController
7.( SOAM 的实例。Web.Controllers.HomeController
8.( Container.GetInstance(SOAM.Web.Controllers.HomeController(

有什么想法可以解决这个问题吗?

结构图 3 多重装饰

DecorateAllWith默认允许自动布线,并允许以非常简单的方式堆叠装饰器:

For<IGeoCoder>().Use<OviGeoCoder>();
For(typeof(IGeoCoder)).DecorateAllWith(typeof(SqlCachingGeocoder));
For(typeof(IGeoCoder)).DecorateAllWith(typeof(RedisCachingGeocoder));

如果由于某种原因你不能使用 DecorateAllWith((,那么这应该可以工作:

        var container = new Container(
            c =>
                {
                    c.For<IFoo>().Use<Foo>();
                    c.For<IGeoCoder>().Add<OviGeoCoder>().Named("default");
                    c.For<IGeoCoder>()
                        .Add<SqlCachingGeocoder>()
                        .Ctor<IGeoCoder>()
                        .Is(ctx => ctx.GetInstance<IGeoCoder>("default"))
                        .Named("SqlCaching");
                    c.For<IGeoCoder>()
                        .Use<RedisCachingGeocoder>()
                        .Ctor<IGeoCoder>()
                        .Is(ctx => ctx.GetInstance<IGeoCoder>("SqlCaching"));
                });

想要了解使用与添加时有什么区别?看看这里