Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как сделать MEF контейнер синглтоном?  [new]
mabanza
Member

Откуда:
Сообщений: 194
Привет.
Не могу добиться того, чтоб импортируемый айтем стал синглтоном. Мне надо разделять один экземпляр класса для многих UserControl -в.
Пишу по инструкции

CompositionInitializer.SatisfyImports(this);

Выкидывает

Cannot call SatisfyImports on a object of type '...' because it is marked with one or more ExportAttributes

Яснопень оно маркет, оно само потом импортируется другим проектом, поэтому этот класс, который импортирует интересующий меня класс, сам импортируется.

Как это разрулить?
Спасибо.
3 май 13, 00:14    [14255157]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Что за бред? Используйте статик класс.
5 май 13, 21:49    [14260496]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
mabanza
Member

Откуда:
Сообщений: 194
WPF,

Ясно.
Здесь с MEF-ом никто не работает.
Будем искать.
7 май 13, 22:17    [14270335]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Коллега, я работаю с MEF и Prism постоянно. Если вы немного вникнете в тему, вы поймете, что MEF предоставляет в сущности шаблон контрола, в основе импорта лежит рефлексия. Если вы импортировали объект, он уже представлен синглтоном, если хотите. Но подход в работе с MEF зависит от способа реализации discovery service или locator service. Вашему контролу для работы понадобятся и другие сервисы согласно контракта, например IDataAccessService для доступа к данным, IEventAggregator для событий, IOrderService для команд и т.д. Обратите внимание, я говорю не о экземпляре класса, а о контрактах, которыми вы связываете свой контрол. Понятие instance of control в MEF отсутствует, потому что вы работаете с ним (шаблоном) на уровне сервисов. Привыкните к тому, что не вы поднимаете контрол, а ваши сервисы, в отличие от классического MVVM. Обычно в вашем случае я переопределяю ExportAttribute в купе с IViewRegionRegistration, чтобы добавить импортируемому объекту контракт: [AttributeUsage(AttributeTargets.Class, AllowMultiple = true]

Ваш вопрос в этой связи звучит некорректно, непонятно, что вы хотите.
7 май 13, 23:57    [14270767]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
WPF
Коллега, я работаю с MEF и Prism постоянно. Если вы немного вникнете в тему, вы поймете, что MEF предоставляет в сущности шаблон контрола, в основе импорта лежит рефлексия. Если вы импортировали объект, он уже представлен синглтоном, если хотите. Но подход в работе с MEF зависит от способа реализации discovery service или locator service. Вашему контролу для работы понадобятся и другие сервисы согласно контракта, например IDataAccessService для доступа к данным, IEventAggregator для событий, IOrderService для команд и т.д. Обратите внимание, я говорю не о экземпляре класса, а о контрактах, которыми вы связываете свой контрол. Понятие instance of control в MEF отсутствует, потому что вы работаете с ним (шаблоном) на уровне сервисов. Привыкните к тому, что не вы поднимаете контрол, а ваши сервисы, в отличие от классического MVVM. Обычно в вашем случае я переопределяю ExportAttribute в купе с IViewRegionRegistration, чтобы добавить импортируемому объекту контракт: [AttributeUsage(AttributeTargets.Class, AllowMultiple = true]

Ваш вопрос в этой связи звучит некорректно, непонятно, что вы хотите.



Муть и жуть какая-то.
8 май 13, 12:20    [14272809]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
SeVa, тогда уже пора прочитать пару новых книжек по технике современного программирования, и муть и жуть как рукой снимет.
8 май 13, 12:59    [14273159]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
А тебе нужны книжки по азам net, чтобы узнать, что такое [AttributeUsage(AttributeTargets.Class, AllowMultiple = true], а потом прочитать хотя бы одну статью по mef и до тех пор не нести такую пургу
8 май 13, 13:09    [14273236]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Ты наверное меня с МСУ перепутал, соревноваться кто дальше плюнет я не буду, что касается атрибутов, так ты даже и не понял для чего я их в данном случае использую, поясню тебе SeVa, чтобы ты мог в своем MEF контроле указать другой регион, например: [ViewExport(RegionName=RegionNames.LeftSideRegion], а затем ниже [ViewExport(RegionName=RegionNames.RightSideRegion], представляешь SeVa, тогда ты cможешь иметь контрол и слева, и справа, причем динамически, по выбору юзера. Я открыл тебе глаза? Или ты по-прежнему хардкодишь все зависимости вручную?
8 май 13, 14:51    [14274084]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Я тебе больше скажу, SeVa, я сейчас вообще не делаю вызовы классов, представляешь? Вот тебе пример твоего любимого MVVM, только в моем исполнении:

[Export(typeof(PointViewModel)))]
public class PointViewModel : NotificationObject
{
[ImportingConstructor]
public PointViewModel(IContestantService contestantService, IEventAggregator eventAggregator)
//Реализация
}


... и все, как я уже сказал выше, класс в приложении нигде не вызывается
8 май 13, 15:05    [14274209]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
Не создается явно объект, если не вызывается нигде, то он никому не нужен.

Читай буквари
8 май 13, 15:18    [14274302]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Все, я тебя понял, пока не покажешь свой код сюда больше не заходи.
8 май 13, 15:19    [14274314]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
WPF
Ты наверное меня с МСУ перепутал, соревноваться кто дальше плюнет я не буду, что касается атрибутов, так ты даже и не понял для чего я их в данном случае использую, поясню тебе SeVa, чтобы ты мог в своем MEF контроле указать другой регион, например: [ViewExport(RegionName=RegionNames.LeftSideRegion], а затем ниже [ViewExport(RegionName=RegionNames.RightSideRegion], представляешь SeVa, тогда ты cможешь иметь контрол и слева, и справа, причем динамически, по выбору юзера. Я открыл тебе глаза? Или ты по-прежнему хардкодишь все зависимости вручную?



Это ты слышал звон, да не знаешь, где он.
AllowMultiple в MEF никогда не было, иначе можно было бы лепить одновременно Shared & NonShared, сразу видно, что исходники prism не смотрел.
ViewExport - это и есть хардкод с жесткой привязкой кода к визуальной части. View first - левые мультики не в стиле mvvm, от которых в следующей версии prism для winrt отказались.
Discovery Service - левость, которая никакого отношения к MEF не имеет.
Service locator - антипаттерн по мнению разработчиков mef, в котором сделано все, чтобы от него уйти

И тд. Дальше лениво писать
9 май 13, 09:56    [14276856]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
mabanza
Member

Откуда:
Сообщений: 194
WPF,

В самом общем виде я хочу получить экземпляр класса, существующего в проекте А, в проекте В. Проект В не знает ничего (и я принимаю все меры, чтоб он продолжал не знать) о классе А. MEF позволяет мне открыть его как любой из его интерфейсов. И это мне нравится. Но как только я открыл его в одном месте проекта В и популировал, открытие в другом месте дает мне новый экземпляр класса. Я не вижу популированных данных, какие-бы атрибуты я не применял (кстати по умолчанию класс открывается как синглтон, но этого нет в моем случае). Каждый раз открывается новый экзепляр и я не могу это победить.

Так что, сценарий с синглтоном не реализуется?
Спасибо.
9 май 13, 23:31    [14278240]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Вы же наполняете любой контрол на уровне ViewModel. Импортируйте контролы и заполняйте его данными из ViewModel, и будет вам счастье. ViewModel тоже можно импортировать.

Что же касается сценария синглтона, создайте класс, который будет следить за контролом и его данными, только и всего.
12 май 13, 22:33    [14284882]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
mabanza
Привет.
Не могу добиться того, чтоб импортируемый айтем стал синглтоном. Мне надо разделять один экземпляр класса для многих UserControl -в.
Пишу по инструкции

CompositionInitializer.SatisfyImports(this);

Выкидывает

Cannot call SatisfyImports on a object of type '...' because it is marked with one or more ExportAttributes

Яснопень оно маркет, оно само потом импортируется другим проектом, поэтому этот класс, который импортирует интересующий меня класс, сам импортируется.

Как это разрулить?
Спасибо.


Покажи полный код. Есть большие подозрения, что делаешь не то. У mef проблемы с синглетоном могут быть только при многопоточности.
13 май 13, 00:02    [14285142]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
mabanza
Member

Откуда:
Сообщений: 194
SeVa,

Код? Вы шутите? Ну хорошо, вот код:

[Export]
public class DataModelVM : BaseController, IBroadcasting
{
private System.Collections.ObjectModel.ObservableCollection<TablesDTO> contextTables;
public System.Collections.ObjectModel.ObservableCollection<TablesDTO> ContextTables
{
get { return contextTables; }
set { contextTables = value; NotifyPropertyChanged("ContextTables"); }
}

private SystemBroadcastSubscriber subscriber;
SystemBroadcastSubscriber IBroadcasting.Subscriber
{
get { return subscriber; }
set { subscriber = value; }
}
private double _centralContainerHeight;
public double CentralContainerHeight
{
get { return _centralContainerHeight; }
set
{
_centralContainerHeight = value;
NotifyPropertyChanged("CentralContainerHeight");
}
}
...

Вот как его открывает другой аппликэйш:

public partial class PayrollControl : DictionaryCustomBase
{
[Import(typeof(IPayrollDataModel))]
public IPayrollDataModel PayrollDataModel;

public PayrollControl(string CallerURI) : base(CallerURI)
{
InitializeComponent();
a = new BBBSilverlight.Utils.GUI().SetupGUISecurity(this, CallerURI);

CatalogExporter cExporter = new CatalogExporter();
cExporter.OnExport += OnExport;
MP.BusyIndicator.StartAnimation(true);
cExporter.Export(this, "BBBVisualBuilder.xap");
}

private void OnExport(CompositionContainer cContainer, string ErrorStr)
{
MP.BusyIndicator.StopAnimation();
if (!String.IsNullOrEmpty(ErrorStr)) new BBBSilverlight.Helpers.ErrorMessage().ShowError(ErrorStr);
else
{
cContainer.ComposeParts(this);
LayoutRoot.Children.Add(PayrollDataModel as Control);
((DictionaryCustomBase)PayrollDataModel).a = a;
//CompositionInitializer.SatisfyImports(PayrollDataModel);
//ShowDirectoryDialog();
PayrollDataModel.OpenDialog = CreateDirectoryDialog();
}

}...

Вот класс, который занимается экспортом:

public class CatalogExporter
{
/// <summary>
/// This class finds the catalog in the list of assembly or, if not found,
/// download the XAP from the Server's ClientBin folder
/// </summary>
private AggregateCatalog aCatalog;
public delegate void _OnExport(CompositionContainer cContainer, string ErrorStr);
public _OnExport OnExport = null;
private object _container;

public void Export(object aContainer, string CatalogURI)
{
_container = aContainer;

//Check if Catalog exists in the current Assembly list
System.Reflection.Assembly v = AppDomain.CurrentDomain.GetAssemblies().Where(p => p.FullName.Contains(CatalogURI.Split('.')[0])).FirstOrDefault();
if (v != null)
{
AssemblyCatalog result = new AssemblyCatalog(v);
var composer = new CompositionContainer(result);
if (OnExport != null) OnExport(composer, "");
return;
}

//Catalog is not in the Client side assembly set. Download it from the Server
aCatalog = new AggregateCatalog();
aCatalog.Catalogs.Add(CreateCatalog(CatalogURI));
}

private DeploymentCatalog CreateCatalog(string uri)
{
var catalog = new DeploymentCatalog(uri);
catalog.DownloadCompleted += (s, e) => DownloadCompleted(s, e);
catalog.DownloadAsync();
return catalog;
}

private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
DeploymentCatalog result = null;
string errStr="";
if (e.Error != null) errStr=e.Error.InnerException.Message;
else result = e.UserState as DeploymentCatalog;

var composer = new CompositionContainer(result);
if (OnExport != null) OnExport(composer, errStr);
}

}

Пока все ничтяк, этот код работает.

Как только я пытаюсь открывать DataModelVM, еще откуда-нибудь, вылетает ошибка см. выше.
Чего я сделал, так это насильно его прогнул и поместил в ресурсы аппликэшона:

public DataModelVM()
{
try
{
...
App.Current.Resources.Remove("DataModelVM");
App.Current.Resources.Add("DataModelVM", this);

}
catch
{
}
}

Теперь отовсюду я его пользую как синглтон:

DataModelVM.Get()....

Вот метод Get():

public static DataModelVM Get()
{
return (DataModelVM)App.Current.Resources["DataModelVM"];
}

Хорошо. Но это же пОшло, друзья мои. А зачем тогда вся эта потеха под названием MEF?
Вот MEF как раз-таки и не стреляет.
Спасибо.
15 май 13, 01:13    [14296462]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
Ссылку на либу тоже нельзя давать? Класс помечен [Export] атрибутом, у вас все в ваших руках, импортируйте либу, импортируйте данные и объединяйте. А если есть общий класс инициализации, помеченный таким атрибутом, так можно импортировать контрол вместе с данными.

Не показали конструктор DataModelVM, что там в конструкторе, может уже и какая служба прописана? Если нет, в основном приложении добавьте в Bootstrapper.ConfigureAggregateCatalog:
 var catalog = new DirectoryCatalog(“Plugins”)
AggregateCatalog.Catalogs.Add(catalog);
И ваша либа подключится в приложение даже без ссылки и без какого-либо упоминания в проекте. MEF это большая тема, быстро здесь не разобраться, но смотрите на нее, как на клон reflection, и все сразу встанет на свои места, даже контрол можно импортировать вместе с данными, главное атрибут [Export] в нужных местах расставить, а лучше, я уже сказал выше, иметь помеченный таким контрактом класс инициализации либы.
15 май 13, 08:42    [14296764]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
WPF
Ссылку на либу тоже нельзя давать? Класс помечен [Export] атрибутом, у вас все в ваших руках, импортируйте либу, импортируйте данные и объединяйте. А если есть общий класс инициализации, помеченный таким атрибутом, так можно импортировать контрол вместе с данными.

Не показали конструктор DataModelVM, что там в конструкторе, может уже и какая служба прописана? Если нет, в основном приложении добавьте в Bootstrapper.ConfigureAggregateCatalog:
 var catalog = new DirectoryCatalog(“Plugins”)
AggregateCatalog.Catalogs.Add(catalog);
И ваша либа подключится в приложение даже без ссылки и без какого-либо упоминания в проекте. MEF это большая тема, быстро здесь не разобраться, но смотрите на нее, как на клон reflection, и все сразу встанет на свои места, даже контрол можно импортировать вместе с данными, главное атрибут [Export] в нужных местах расставить, а лучше, я уже сказал выше, иметь помеченный таким контрактом класс инициализации либы.


Очередной несвязный набор бреда и полное отсутствие знания темы. Где ты видел DirectoryCatalog в silverlight?
15 май 13, 11:51    [14297900]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
mabanza
Хорошо. Но это же пОшло, друзья мои. А зачем тогда вся эта потеха под названием MEF?
Вот MEF как раз-таки и не стреляет.
Спасибо.


Не в обиду, но нечего на MEF пенять...

1. Если контрол создается несколько раз, то из-за отсутствия проверки, сборки будут повторно подгружаться.Сама идея грузить их из контрола дурно пахнет.
2. Контейнер должен быть синглтоном, а у тебя он создается сорок восемь раз, нет ничего удивительного, что твой vm не shared.

Рекомендую взять загрузчик модулей из prism, почитать там доки на тему как правильно работать с mef, грузить сборки при инициализации приложения и убрать эту муть из контрола(должен соблюдаться принцип единичной ответственности)
15 май 13, 11:52    [14297908]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
SeVa
Очередной несвязный набор бреда и полное отсутствие знания темы. Где ты видел DirectoryCatalog в silverlight?

SeVa, ты поражаешь своей безграмотностью, тебе сюда: Modularity QuickStarts for Silverlight
Там в конце странички как раз для тебя примерчик:
protected override void ConfigureAggregateCatalog()
{
    base.ConfigureAggregateCatalog();
    // Add this assembly to export ModuleTracker.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));

    // Module A is referenced in in the project and directly in code.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly));

    // Module C is referenced in in the project and directly in code.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
}
15 май 13, 12:51    [14298492]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
WPF
SeVa
Очередной несвязный набор бреда и полное отсутствие знания темы. Где ты видел DirectoryCatalog в silverlight?

SeVa, ты поражаешь своей безграмотностью, тебе сюда: Modularity QuickStarts for Silverlight
Там в конце странички как раз для тебя примерчик:
protected override void ConfigureAggregateCatalog()
{
    base.ConfigureAggregateCatalog();
    // Add this assembly to export ModuleTracker.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));

    // Module A is referenced in in the project and directly in code.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly));

    // Module C is referenced in in the project and directly in code.
    this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
}


А ты своей тупостью. Очередной говнорецепт, который совершенно не в тему. AsseblyCatalog и DirectoryCatalog - две большие разницы. В сильверлайте сборки расположены удаленно, для их динамической загрузки нужен DeploymentCatalog.
15 май 13, 13:14    [14298727]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
mabanza
Member

Откуда:
Сообщений: 194
Хороший форум. Я давно тут не был и, наверное, опять долго не буду. Кроме пожеланий и лозунгов типа "MEF - сложная тема", а также переругиваний друг с другом, ничего.
И на том спасибо.
15 май 13, 16:49    [14300738]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
SeVa
Member [заблокирован]

Откуда: Москва
Сообщений: 4324
Ну, лозунги на MEF ты сам навешивал. Ничего в нем сложного нет, если понять основные принципы его работы, которых очень немного.
Изучи сначала матчасть
15 май 13, 18:02    [14301188]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
SeVa, нашел к чему прицепиться? Ну, злорадствуй теперь, от этого суть моей мысли не меняется, ты вообще ничего еще не предложил по теме.

ТС, тут на пальцах не объяснишь, сходи сюда, ознакомься Managed Extensibility Framework Идею я тебе верную предлагаю, кода кинуть не могу, я в SL только с Unity работал. По возможности добавить атрибуты к сборке и импортировать ее в runtime, для этого нужно добавить ее в список сборок для приложения, тогда нужна ссылка на либу, если и это сделать нельзя, тогда можно добавить либу через конфигурационный файл. Для SL есть несколько способов подгрузки сборок тоже, если дружишь с буржуйским, вот тебе несколько ссылок, где объясняют на пальцах:

MEF & Silverlight 4 Beta - Part 1, Introduction

MEF & Silverlight 4 Beta - Part 5, the PackageCatalog

MEF & Silverlight 4 Beta - Part 3, Catalogs

MEF & Silverlight 4 Beta - Part 2, Imports & Exports
16 май 13, 02:21    [14302884]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать MEF контейнер синглтоном?  [new]
WPF
Member

Откуда:
Сообщений: 88
mabanza
Хороший форум. Я давно тут не был и, наверное, опять долго не буду. Кроме пожеланий и лозунгов типа "MEF - сложная тема", а также переругиваний друг с другом, ничего.
И на том спасибо.
Это интернет, детка... здесь тоже троли есть. Скажу тебе больше, пару лет назад, я попросил модератора bured разбанить SeVa из вечного бана за то что он срался с МСУ, теперь жалею, форум получил вместо грамотного спеца локального троля
16 май 13, 02:28    [14302894]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / WPF, Silverlight Ответить