Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
KeBJIaP
145 / 142 / 32
Регистрация: 21.01.2012
Сообщений: 545
Завершенные тесты: 1
1

MEF. Не работает SatisfyImportsOnce при ImportMany

26.08.2016, 16:21. Просмотров 270. Ответов 0
Метки нет (Все метки)

Разбираюсь с MEF.
Делаю пример практически такой же как в msdn с калькулятором.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using fs;
using System.ComponentModel.Composition;
 
 
namespace ConsoleApplication2 {
    
 
    class Program
    {
        static void Main(string[] args){
            ICalc calc = new Calculator();
            Console.WriteLine( calc.Calc('+', 123, 111));
            Console.ReadLine();
        }
    }
 
    public interface ICalc
    {
        string Calc(char operand, double arg1, double arg2);
    }
 
    public class Calculator : ICalc
    {
        CompositionContainer cont;
 
        [ImportMany(typeof(IOperation))]
        private IEnumerable<Lazy<IOperation, IOperationData>> operations;
 
        [Import(typeof(IMessage))]
        private IMessage Mess;
 
        public Calculator(){
            InitMef();
        }
 
       
 
        private void InitMef(){
            var cat = new AggregateCatalog();
            cont = new CompositionContainer(cat);
            cat.Catalogs.Add(new AssemblyCatalog(Assembly.GetCallingAssembly()));   
            DirectoryInfo di = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);
            var p =Path.Combine(di.Parent.Parent.Parent.Parent.FullName, @"ClassLibrary1\bin\Debug");
            cat.Catalogs.Add(new DirectoryCatalog(p));
            cont.SatisfyImportsOnce(this);
        }
 
        public string Calc(char operand, double arg1, double arg2){
            Lazy<IOperation> _utah = operations.Where(s => s.Metadata.Symbol == operand).FirstOrDefault();
            if(_utah!=null){
                    return _utah.Value.Operate(arg1, arg2).ToString();
            }
            return Mess.Message();
        }
    }
   
    public interface IOperation
    {
        double Operate(double arg1, double arg2);
    }
 
    public interface IOperationData
    {
        char Symbol { get; }
    }
 
    [Export(typeof(IOperation))]
    [ExportMetadata("Symbol","+")]
    public class SumOperation : IOperation
    {
        public double Operate(double arg1, double arg2){
            return arg1 + arg2;
        }
    }
 
    [Export(typeof(IOperation))]
    [ExportMetadata("Symbol", "-")]
    public class SubOperation : IOperation {
        public double Operate(double arg1, double arg2) {
            return arg1 + arg2;
        }
    }
 
    public interface IMessage
    {
        string Message();
    }
 
}
Проблема в методе InitMef()
Пошагово смотрю исполнение:
в строке cont.SatisfyImportsOnce(this); каталог имеет 4 части, как и нужно.
Часть соответствующая IMessage нормально инстанцируется, а мой
C#
1
2
 [ImportMany(typeof(IOperation))]
        private IEnumerable<Lazy<IOperation, IOperationData>> operations;
ни в какую не хочет. Сравнивал с примером до рези в глазах, перелопатил гугл, никак не могу понять почему не работает.

Добавлено через 1 час 3 минуты
Заменил
C#
1
2
        [ImportMany(typeof(IOperation))]
        private IEnumerable<Lazy<IOperation, IOperationData>> operations;
на
C#
1
2
        [ImportMany(typeof (IOperation))] 
        private IEnumerable<Lazy<IOperation, IDictionary<string, object>>> operations;
и все заработало. Не понимаю все равно, вроде нормально объявлен был интерфейс метадаты...

Добавлено через 3 минуты
Поменял все обратно, все равно работает o_O
Похоже, был баг студии

Добавлено через 6 минут
В общем программа начинает работать после изменения типа
C#
1
2
3
public interface IOperationData {
        char Symbol { get; }
    }
на
C#
1
2
3
    public interface IOperationData {
        string Symbol { get; }
    }
Добавлено через 11 минут
Разобрался окончательно. В объявлении аттрибута
C#
1
[ExportMetadata("Symbol", '+')]
тип аттрибута должен соответствовать типу метаданных, объявленных в интерфейсе
C#
1
2
3
    public interface IOperationData {
        char Symbol { get; }
    }
1
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.08.2016, 16:21
Ответы с готовыми решениями:

Mef и контракты
начал разбираться с mef, в доках написано что контракты должны совпадать, то...

MEF и создание расширяемого приложения
Итак, на создание этой темы меня толкнуло желание поделиться тем немногим, что...

Реализация Managed Extensibility Framework (MEF)
Вечер добрый, не как не могу понять принцип обмена информацией между...

MEF. Выборочная загрузка. Фильтрация модулей.
Пишу приложение с поддержкой системы плагинов. Не могу разобраться как сделать...

MEF создание элементов в разных потоках
Может кто-нибудь разьяснить в чем подвох? Вьідает ошибку на єтапе...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2016, 16:21

Работа с MEF. Инъекция зависимостей через конструктор
Кто-нибудь шарит в MEF? Вообщем у меня проблема следующего характера, хочу...

MEF создание единого репозитория для запроса
В продолжение єтой темы......

MEF from Attribute. Дэбаг показывает, что StatusService == null
Есть контроллер public class ScreenController : BaseController {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru