C# MEF和工厂,直接导入创建的对象

C# MEF和工厂,直接导入创建的对象,c#,import,mef,factory,C#,Import,Mef,Factory,我已经开始和MEF合作了。在我的应用程序中,我为一些模型建立了一个工厂。 我的工厂有2种创建方法;一个接受名称作为参数,另一个接受类型 [Export(typeof(IFactory))] [PartCreationPolicy(CreationPolicy.Shared)] public class MyFactory : IFactory { public IModel Create(String name) {...} public IModel Create(Type t

我已经开始和MEF合作了。在我的应用程序中,我为一些模型建立了一个工厂。 我的工厂有2种创建方法;一个接受名称作为参数,另一个接受类型

[Export(typeof(IFactory))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyFactory : IFactory
{
    public IModel Create(String name) {...}
    public IModel Create(Type type) {...}
}

public class Foo
{
    [Import(typeof(IFactory))]
    public IFactory Factory { get; set; }

    public Foo()
    {
        IModel modelByName = Factory.Create("name");
        IModel modelByType = Factory.Create(typeof(Foo));
    }
}
目前,我必须导入一个工厂,然后调用create 在factory对象上获取模型。 现在我想知道是否有直接导入模型的方法,例如:

[Import(typeof(IModel), Name:"Name")]
public IModel Model { get; set; }
编辑---------------------------------------------------

我们的目标是替换如下内容:

public class Foo
{
    [Import(typeof(IFactory))]
    public IFactory Factory { get; set; }

    public IModel Model { get; set; }
    public IModel Model1 { get; set; }

    public Foo()
    {
        Model = Factory.Create("Foo");
        Model1 = Factory.Create(typeof(Foo1));
    }
}
public class Foo
{
    //Should internal import a IFactory(singeleton) object 
    //and call the Create(name:String) method on it
    [Import(typeof(IModel), Name:"Foo")]
    public IModel Model { get; set; }

    //Should internal import a IFactory(singeleton) object 
    //and call the Create(type:Type) method on it
    [Import(typeof(IModel), Type: typeof(Foo1))]
    public IModel Model1 { get; set; }
}
public class Foo
{
    //Import using the contract name.
    [Import("Foo1", typeof(IModel))]
    public IModel Model1 { get; set; }

    //Import using the actual type.
    [Import(typeof(Foo2))]
    public IModel Model2 { get; set; }

    //Import the same model but with contract name instead of type. 
    //This is possible because there are two different exports.
    [Import("Foo2")]
    public IModel Model3 { get; set; }
}    
比如说:

public class Foo
{
    [Import(typeof(IFactory))]
    public IFactory Factory { get; set; }

    public IModel Model { get; set; }
    public IModel Model1 { get; set; }

    public Foo()
    {
        Model = Factory.Create("Foo");
        Model1 = Factory.Create(typeof(Foo1));
    }
}
public class Foo
{
    //Should internal import a IFactory(singeleton) object 
    //and call the Create(name:String) method on it
    [Import(typeof(IModel), Name:"Foo")]
    public IModel Model { get; set; }

    //Should internal import a IFactory(singeleton) object 
    //and call the Create(type:Type) method on it
    [Import(typeof(IModel), Type: typeof(Foo1))]
    public IModel Model1 { get; set; }
}
public class Foo
{
    //Import using the contract name.
    [Import("Foo1", typeof(IModel))]
    public IModel Model1 { get; set; }

    //Import using the actual type.
    [Import(typeof(Foo2))]
    public IModel Model2 { get; set; }

    //Import the same model but with contract name instead of type. 
    //This is possible because there are two different exports.
    [Import("Foo2")]
    public IModel Model3 { get; set; }
}    

您不能将
[Import]
属性的参数传递给正在导入的类型的方法

但是,如果可以的话,我认为您不应该这样做,因为这样做会导致类被构造,并且很可能会过早地构造。您应该将对象的构造延迟到实际需要的时间。通过直接导入,您将失去这种懒惰行为


此外,工厂通常需要一些参数来构造类型,但这里的情况并非如此。如果必须直接导入,则只需导入类型本身,而不必导入工厂(当然,您将失去以后通过更改工厂行为轻松操作构造的选项)。

您不能将
[import]
属性的参数传递给导入类型的方法

但是,如果可以的话,我认为您不应该这样做,因为这样做会导致类被构造,并且很可能会过早地构造。您应该将对象的构造延迟到实际需要的时间。通过直接导入,您将失去这种懒惰行为


此外,工厂通常需要一些参数来构造类型,但这里的情况并非如此。如果您必须直接导入,您可以只导入类型本身,而不是工厂(当然,您将失去以后通过更改工厂行为轻松操纵构造的选项)。

您可以将合同名称添加到导出中,然后在导入零件时使用它们

对于
IModel
界面:

public interface IModel { }
您可以使用合同名称将实现导出为
IModel

[Export("Foo1", typeof(IModel))]
public class Foo1 : IModel { }
还可以在单个类上添加多个导出属性。这样,您可以同时满足两种导入(按名称和类型)

然后像这样导入:

public class Foo
{
    [Import(typeof(IFactory))]
    public IFactory Factory { get; set; }

    public IModel Model { get; set; }
    public IModel Model1 { get; set; }

    public Foo()
    {
        Model = Factory.Create("Foo");
        Model1 = Factory.Create(typeof(Foo1));
    }
}
public class Foo
{
    //Should internal import a IFactory(singeleton) object 
    //and call the Create(name:String) method on it
    [Import(typeof(IModel), Name:"Foo")]
    public IModel Model { get; set; }

    //Should internal import a IFactory(singeleton) object 
    //and call the Create(type:Type) method on it
    [Import(typeof(IModel), Type: typeof(Foo1))]
    public IModel Model1 { get; set; }
}
public class Foo
{
    //Import using the contract name.
    [Import("Foo1", typeof(IModel))]
    public IModel Model1 { get; set; }

    //Import using the actual type.
    [Import(typeof(Foo2))]
    public IModel Model2 { get; set; }

    //Import the same model but with contract name instead of type. 
    //This is possible because there are two different exports.
    [Import("Foo2")]
    public IModel Model3 { get; set; }
}    

正如您所看到的,您根本不必使用ant factory。MEF将是您的工厂。

您可以将合同名称添加到出口中,然后在导入零件时使用它们

对于
IModel
界面:

public interface IModel { }
您可以使用合同名称将实现导出为
IModel

[Export("Foo1", typeof(IModel))]
public class Foo1 : IModel { }
还可以在单个类上添加多个导出属性。这样,您可以同时满足两种导入(按名称和类型)

然后像这样导入:

public class Foo
{
    [Import(typeof(IFactory))]
    public IFactory Factory { get; set; }

    public IModel Model { get; set; }
    public IModel Model1 { get; set; }

    public Foo()
    {
        Model = Factory.Create("Foo");
        Model1 = Factory.Create(typeof(Foo1));
    }
}
public class Foo
{
    //Should internal import a IFactory(singeleton) object 
    //and call the Create(name:String) method on it
    [Import(typeof(IModel), Name:"Foo")]
    public IModel Model { get; set; }

    //Should internal import a IFactory(singeleton) object 
    //and call the Create(type:Type) method on it
    [Import(typeof(IModel), Type: typeof(Foo1))]
    public IModel Model1 { get; set; }
}
public class Foo
{
    //Import using the contract name.
    [Import("Foo1", typeof(IModel))]
    public IModel Model1 { get; set; }

    //Import using the actual type.
    [Import(typeof(Foo2))]
    public IModel Model2 { get; set; }

    //Import the same model but with contract name instead of type. 
    //This is possible because there are two different exports.
    [Import("Foo2")]
    public IModel Model3 { get; set; }
}    

正如您所看到的,您根本不必使用ant factory。MEF将是您的工厂。

谢谢您的回答…我认为我的问题不够准确,我不想替换工厂,但我希望直接导入Create方法的返回值,因此我不必每次都创建一个因子,只需调用Create即可。谢谢您的回答…我认为我的问题不够准确,我不想替换工厂,但我想直接得到导入的Create方法的返回值,所以我不必每次都创建一个factor,只需调用Create。为什么我要使用dynamic关键字,我知道导入的对象是IModel类型的。我要寻找的是一种在属性上放置属性并将字符串或类型作为参数的方法。这个属性现在应该将参数传递给Create方法,并将Create的返回值存储在属性中……我在问题中添加了一个伪示例。谢谢您的回答。你是对的;如果我有一个用export属性修饰的类,这将是可行的。但是你看到编辑过的问题了吗?工厂会根据给定的字符串或类型(Create(type:type)、Create(name:string))…导入工厂创建的对象(注意:我应该能够在导入端指定字符串或类型)@user1320170那么我相信您真正需要的是像Autofac这样的IoC容器(顺便说一下,它与MEF集成)。有一种方法可以使用MEF实现这一点,但您必须添加另一层抽象,这样您的解决方案就会变得复杂。如果您计划在许多地方使用此模式,那么情况会更糟。谢谢我来看看。为什么我要使用dynamic关键字,我知道导入的对象是IModel类型。我很抱歉oking for是一种在属性上放置属性并为该属性指定字符串或类型作为参数的方法。该属性现在应该将参数传递给Create方法,并将Create的返回值存储在属性中…我为该问题添加了一个伪示例。感谢您的回答。您是对的;如果我有一个c用导出属性修饰的lass。但是你看到编辑过的问题了吗?工厂根据给定的字符串或类型(Create(type:type)、Create(name:string))…有没有方法导入工厂创建的对象(注意:我应该能够在导入端指定字符串或类型)@用户1320170那么我相信您真正需要的是一个IoC容器,比如Autofac(顺便说一下,它与MEF集成)。有一种方法可以使用MEF实现这一点,但您必须添加另一层抽象,这样您的解决方案就会变得复杂。如果您计划在许多地方使用此模式,那么情况会更糟。谢谢,我将查看它