【问题标题】:Pass parameters to constructor, when initializing a lazy instance初始化惰性实例时将参数传递给构造函数
【发布时间】:2010-12-09 09:40:05
【问题描述】:

据我所知,如果一个变量被声明为Lazy,那么当我们使用Value 属性时,它的构造函数就会被调用。

我需要将一些参数传递给这个Lazy 实例,但找不到正确的语法。 这不是我的设计,我使用的是 MEF 和 ExportFactory,它返回了我的零件的 Lazy 实例。我的零件有构造函数,我需要用一些参数调用这些构造函数。

【问题讨论】:

    标签: c# constructor mef lazy-initialization


    【解决方案1】:

    您可以导出自己的Func

    public class FooFactory
    {
        [Export(typeof(Func<string,int,ExportLifetimeContext<IFoo>>))]
        public ExportLifetimeContext<IFoo> CreateFoo(string param1, int param2)
        {
            Foo foo = new Foo(param1, param2);
            return new ExportLifetimeContext<IFoo>(foo,
                delegate
                {
                    // Clean-up action code goes here. The client might not be able 
                    // to do this through the IFoo interface because it might not
                    // even expose a Dispose method.
                    //
                    // If you created other hidden dependencies in order to construct
                    // Foo, you could also clean them up here. 
                    foo.Dispose();
                });
        }
    }
    

    并将其导入其他地方:

    [Export(typeof(ISomething))]
    public class FooUser : ISomething
    {
        private readonly Func<string,int,ExportLifetimeContext<IFoo>> fooFactory;
    
        [ImportingConstructor]
        public FooUser(Func<string,int,ExportLifetimeContext<IFoo>> fooFactory)
        {
            this.fooFactory = fooFactory;
        }
    
        public void DoSomething()
        {
            using (var fooLifetime = this.fooFactory("hello", 3))
            {
                IFoo foo = fooLifetime.Value;
                ...
            }
        }
    }
    

    如果您不需要清理操作,那么您可以通过丢弃所有 ExportLifetimeContext 内容来大大简化此操作。

    但是,IFoo 的某些实现可能是一次性的(或依赖于其他一次性对象),而另一些则不是。所以最正确的做法是在抽象中构建一个“我已经完成了这个对象”的信号,这就是ExportLifetimeContext 提供的。

    【讨论】:

    • 在我的情况下,零件并不完全受信任。此外,由于我不知道(从出口商方面)谁在调用导出的 Func,所以我需要一些标识符作为函数的参数传递。这样,该部分就声称他是谁。这是一个安全漏洞,因为一个部件可以声称是其他人,我会将另一部件的敏感数据返回给这个部件。这个问题可以在我创建对象时通过设计来解决。那时,使用元数据,我知道我正在创建哪个部分,并且可以轻松地将其特定依赖项注入其构造函数。
    • @Wim:我从文件夹加载插件。您的 Foo foo = new Foo(param1, param2) 行给了我一个问题,因为我在实施时不知道“Foo”。这适用于 ExportFactory,但现在我需要将参数传递给插件中的一种 ViewModel。有什么建议吗?
    • @PatrickS:我想您可以自己扫描程序集以查找实现IFoo 的类型,然后通过反射调用构造函数。这有点超出原始问题的范围,无法在此处详细回答,因为我认为 MEF 对此没有多大帮助。
    【解决方案2】:

    当您使用 ExportFactory 创建零件时,MEF 没有内置方法可让您将构造函数参数传递给零件。像 Wim Coenen 所建议的那样可能是实现您想要的最佳方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多