#c# #unity-container #prism
#c# #unity-контейнер #prism
Вопрос:
В нашем приложении prism нам нужно загрузить модуль в центральную панель, когда пользователь нажимает элемент в дереве (отдельный модуль). Модуль в центральной панели (скажем, модуль конструктора) может открыть файл и отобразить себя, если ему указан путь. Как я могу передать путь к файлу в этот модуль? Например
в модуле Designer
public DesignerViewModel(DataAccess dataAccess)// This will be injected
{
}
//The following class can create the model objects using the IDataService for getting data from remote location
public DataAccess(IDataService service)//this will be injected
{
}
Объект доступа к данным является локальным для модуля Designer, поэтому я не хотел бы предоставлять его извне модуля. Итак, регистрация выполняется в модуле
public class DesignerModule : IModule
{
public void Initialize()
{
var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
container.RegisterType<Object, DesignerView>("DesignerUI");
container.RegisterType<DataAccess>();
}
}
IDataService зарегистрирован на уровне приложения
public class BootStrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IDataService, DataService>();
}
}
Обратите внимание, что IDataService является синглтоном для всего приложения. Я не могу передать путь к файлу, который относится к экземпляру модуля в IDataService. Обратите внимание, что вы можете открыть любое количество модулей в центральной панели по своему усмотрению, просто нажмите на элемент дерева -> дерево запустит событие с выбранным идентификатором элемента -> приложение найдет путь, соответствующий идентификатору элемента, и вызовет модуль.
Как я буду передавать путь, когда я говорю _regionManager.AddToRegion(«CenterRegion», DesignerModule); Prism прекрасно выполнит все инъекции зависимостей, но как передать путь — большой вопрос?
Ответ №1:
Вы можете использовать EventAggregator для обмена сообщениями с модулями beetwen. Каждый модуль подписывается на EventAggregator. При открытии модуля вы можете отправить на host control уведомление о новорожденном. Управление хостом отправляет ответ обратно с данными инициализации.
public class MessageEvent : CompositePresentationEvent<Message>{}
internal class MessageReceiver
{
private readonly MessageEvent _evt;
private readonly string _myId = Guid.NewGuid().ToString();
internal MessageReceiver(IEventAggregator eventAggregator)
{
_evt = eventAggregator.GetEvent<MessageEvent>();
_evt.Subscribe(Receive, true);
_evt.Publish(new Message { Source = _myId, Command = Message.Commands.WhoIAm });
}
public void Receive(Message message)
{
switch (message.Command)
{
case Message.Commands.WhoIAm:
_evt.Publish(
new Message
{
Destination = message.Source,
Command = Message.Commands.Initialize,
MessageData = Encoding.UTF8.GetBytes("init data")
});
break;
case Message.Commands.Initialize:
if (message.Destination == _myId)
{
//init
}
break;
}
}
}
public class Message
{
public enum Commands { Initialize, WhoIAm }
public string Source { get; set; }
public string Destination { get; set; }
public Commands Command { get; set; }
public byte[] MessageData { get; set; }
}
Комментарии:
1. @Radik- это не совсем то, что я хочу. Обратите внимание, что само создание модуля происходит из-за события из модуля дерева, которое включает информацию о пути. Это событие будет обработано основным приложением, и основное приложение создаст модуль конструктора в центральной панели приложения. Я бы предпочел передавать информацию о пути в момент создания экземпляра модуля.
Ответ №2:
Я узнал ответ от своего коллеги.Параметры могут быть переопределены вашими собственными объектами при вызове Resolve(). Итак, создайте объект, который будет введен, заполните его и передайте с помощью Resolve<>() с параметром OVERRIDE. Найдите ParameterOverride в Google для получения дополнительной информации.