Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
191 views
in Technique[技术] by (71.8m points)

c# - MEF Constructor Injection

I'm trying to figure out MEF's Constructor Injection attribute. I have no idea how I tell it to load the constructor's parameters.

This is the property I'm trying to load

[ImportMany(typeof(BUsers))]
public IEnumerable<BUsers> LoadBUsers { get; set; }

Here is the code I'm using to import the assemblies.

try
{
    var catalog = new AggregateCatalog();
    catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
    catalog.Catalogs.Add(new DirectoryCatalog("DI")); 
    var container = new CompositionContainer(catalog);
    container.ComposeParts(this);
}

Here is the class I'm trying to load

[Serializable]
[Export(typeof(BUsers))]
public class EditProfile : BUsers
{
    [ImportingConstructor]
    public EditProfile(string Method, string Version)
    {            
        Version = "2";
        Action = "Edit";
        TypeName = "EditProfile";
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you use the ImportingConstructor attribute, the parameters to the constructor become imports. By default, what you are importing (the contract name) is based on the type of the parameter or property that your are importing into. So in this case the contract type for both your imports is string, and there's no real difference between the first and second parameter.

It looks like you are trying to use imports to supply configuration values, which isn't necessarily what it was designed for. To get it to do what you want, you should override the contract name for each of the parameters, like this:

[ImportingConstructor]
public EditProfile([Import("Method")] string Method, [Import("Version")] string Version)
{ }

Then you need exports for Method and Version in your container. One way to do this is just to add them directly:

var container = new CompositionContainer(catalog);
container.ComposeExportedValue("Method", "MethodValue");
container.ComposeExportedValue("Version", "2.0");
container.ComposeParts(this);

(Note that ComposeExportedValue is actually an extension method defined on the static AttributedModelServices class.)

If you want to read these values from a configuration file of some sort, you could create your own export provider which reads the configuration and provides the values in it as exports to the container.

An alternative way to handle this would be to just import an interface that provides access to the configuration values by name, and get the values you need from the body of the constructor.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...