Extending DialogService in Prism - wpf

On the Prism Library website there is a few notes about Simplify your Application Dialog APIs.
https://prismlibrary.com/docs/wpf/dialog-service.html
Let's say I have a Solution with multiple projects, MainProject, Modules.Module1, CoreProject. So creating this DialogServiceExtensions class in my Core project.
public static class DialogServiceExtensions
{
public static void ShowNotification(this IDialogService dialogService, string message, Action<IDialogResult> callBack)
{
dialogService.ShowDialog(nameof(NotificationDialog), new DialogParameters($"message={message}"), callBack, "notificationWindow");
}
}
I also put NotificationDialog and NotificationDialogViewModel in my Core project
I can call it at any project/module, but the question is how can I tell prism that NotificationDialog ViewModel is NotificationDialogViewModel.
Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
}

Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
If the app wants to show a dialog, you have to do this, as modules are essentially optional (they can be swapped out after deployment or they don't need to exist).
If a module wants to show a dialog (and not the app), you can decide whether it's part of your app's interface to its modules (then put the registration in the app) or not (then put it in the module, each module that uses it, that is, registrations may override each other).

Related

Prism Library Dialog Service

The following sample never worked for me:
https://prismlibrary.com/docs/wpf/dialog-service.html
Where the dialogService comming from?
public MainWindowViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
}
How can I add the dialog service?
protected override Window CreateShell()
{
var w = Container.Resolve<MainWindow>();
return w;
}
It's have to go within the RegisterTypes?
Where the dialogService comming from?
From the container. When resolving, the container also resolves all dependencies.
How can I add the dialog service?
You don't have to and normally should shouldn't either. Most of the time, the default implementation provided by the prism framework suffices.
It's have to go within the RegisterTypes?
If you use Unity, every non-concrete type has to be registered to be able to be resolved. That means, prism's dialog service implementation is registered somewhere. Have a look at the code of your application's base class as a starting point.

Registering Startup Class In Nancy Using AutoFac Bootstrapper

I've been reading through a lot of the Jabbr code to learn Nancy and trying to implement many of the same patterns in my own application. One of the things I can't seem to get working is the concept of an on application start class. The Jabbr code base has an App_Start folder with a Startup.cs file (here) in it with the following implementation.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
...
SetupNancy(kernel, app);
...
}
}
private static void SetupNancy(IKernel kernel, IAppBuilder app)
{
var bootstrapper = new JabbRNinjectNancyBootstrapper(kernel);
app.UseNancy(bootstrapper);
}
When I tried to do something similar to that in my project the Startup.cs file was just ignored. I searched the Jabbr code base to see if it was used anywhere but I wasn't able to find anything and the only differences I could see is Jabbr uses Ninject while I wanted to use AutoFac
Is there a way to register a startup class in nancy?
Take a look at my project over on GitHub, you'll be interested in the Spike branch and may have to unload the ChainLink.Web project to run I can't remember.
I had some trouble finding a way to configure the ILifetimeScope even after reading the accepted answer here by TheCodeJunkie. Here's how you do the actual configuration:
In the bootstrapper class derived from the AutofacNancyBootstrapper, to actually configure the request container, you update the ILifetimeScope's component registry.
protected override void ConfigureRequestContainer(
ILifetimeScope container, NancyContext context)
{
var builder = new ContainerBuilder();
builder.RegisterType<MyDependency>();
builder.Update(container.ComponentRegistry);
}
The application container can be updated similarly in the ConfigureApplicationContainer override.
You should install the Nancy.Bootstrappers.Autofac nuget, inherit from the AutofacNancyBootstrapper type and override the appropriate method (depending on your lifetime scope requirements: application or request). For more info check the readme file https://github.com/nancyfx/nancy.bootstrappers.autofac
HTH
After following the advice from TheCodeJunkie you can use the Update method on the ILifetimeScope container parameter which gives you a ContainerBuilder through an Action:
protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
{
container.Update(builder =>
{
builder.RegisterType<MyType>();
});
}

Event upon initialization complete in WPF/Prism app

In non-Prism WPF app, if I want to run code after initialization (e.g. execute the task specified by command-line argument), I can do it in Loaded event of the main window. However with Prism, the modules are initialized after main window is displayed, that is, IModule.Initialize() is called after Bootstrapper.CreateShell() and Bootstrapper.InitializeShell(). In this case which event/override should I use?
The last thing called by UnityBootstrapper.Run(bool runWithDefaultConfiguration) is InitializeModules() (well apart from a call to Logger.Log). So overide Run(...).
class Bootstrapper : UnityBootstrapper
{
...
public override void Run(bool runWithDefaultConfiguration)
{
base.Run(runWithDefaultConfiguration);
// modules (and everything else) have been initialized when you get here
}
}

Common EJB Client Jar for various modules under the same EAR

Hello brothers in code!
First question here so I'll try my best to respect all the standards. Correct me if I skip anything and I'll fix it right away.
I'm kind of confused about the approach I should take with my application. I have several EJB projects and JSF projects under the same EAR and, of course, I'd like to define some local interfaces for all of the EJB projects. I have a persistence layer with a couple of modules insipierd by the EAO pattern and an access point to the bussiness layer through a Session Façade.
My intention is to make a "SharedInterfaces" Jar that contains all the Client interfaces (All EJB Client jars in one, if I must say) and all the Interfaces that the entities will implement so I can abstract the projects between themselves (no dependencies, just common interfaces to work together).
How can I turn this "SharedInterfaces" project into a common EJB CLient Jar to be used by all the modules? On the other hand, I can make some interface extension so I don't have to configure a project... still I'm not sure if this common project is on the "best practices" approach.
Well, I pretty much figured it out myself.
The SharedInterfaces project defines the interfaces to be commonly used and when I want to make a LocalInterface for an EJB I simply leave that interface blank and extend the one I defined on SharedInterfaces. The container seems to handle it allright because the interface is a local interface after all (sort of).
Just for the sake of clarity I'll add a simple example of what I did. This is the local interface I create for an EJB:
package org.myapp.managers;
import javax.ejb.Local;
#Local
public interface UserManagerLI extends IUserManager{
}
Then, on SharedInterfaces I simply add the interface IUserManager:
public interface IUserManager {
public IUser newUser();
public void saveOrUpdate(IUser u, boolean hashPass);
public void deleteUser(IUser u);
public boolean checkUserAvailability(String username);
public IUser getUser(String username);
}
Then, to use it I simply made the injection as usual:
#ManagedBean
#SessionScoped
public class LogInBean {
#EJB
private IUserManager userManager;
// Attributes, Setters, Getters and methods
}
Of course, one should ALWAYS be careful about what does he expose. Thinking of the interfaces as contracts of service, one should not be able to access functions he is not supossed to access.

MEF and loading EntityTypeConfiguration in runtime

You cannot vote on your own post
0
Hi.
I am developing this (http://arg-co.com/SabteNam%20-%20Copy.zip) windows application, and for my DAL I use Entity Framework. But every single extension has its own EntityTypeConfiguration, so I decided to use [Import] and [Export] to add them in OnModelCreating method of my DbContext.The problem here is that, in 'SabteNamDbContext' class which is located on 'SabteNamDataAccess' library, the '_Configs' is not initialized so I cant iterate it and add its items to 'modelBuilder.Configurations'.
In the source code of 'SampleConfiguration' class, I commented out '[Export(typeof(IDbConfiguration))]' but even Uncommenting this part of code, do not cause application to work properly.
Intresting point is that, if I use the following code in 'Main' windows form, the '_Configs' would be initialized :
[ImportMany(typeof(IDbConfiguration))]
public IEnumerable<EntityTypeConfiguration<object>> _Configs { get; set; }
How can this be fixed ?
While I realize this is probably no longer of use to you, we use a variation on this model from OdeToCode, which I advise you read.
In our case, we have created an interface for our extensions in general, not just for the entity configuration like Scott did, which allows us not only to load the configurations, but also factory and test data per extension, add new permission types to the core application, etc.
Our OnModelCreating looks something like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// load core object mappings
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Configurations.Add(new PermissionConfiguration());
// get plugin assemblies
var catalog = new DirectoryCatalog("bin");
var container = new CompositionContainer(catalog);
container.ComposeParts();
var plugins = container.GetExportedValues<IPlugin>();
// load plugin object mappings
foreach (IPlugin plugin in plugins)
{
plugin.RegisterDomainEntities(modelBuilder.Configurations);
}
base.OnModelCreating(modelBuilder);
}

Resources