Reputation: 464
For example, I create WPF application and want to add some logic that I use at each my application - like logging, unhandled exception handling, etc. I use code like this (it doesn't matter what it actually does - just code that does something) in my example WPF application:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
ServiceInjector.InjectServices();
base.OnStartup(e);
MainWindow window = new MainWindow();
window.Show();
}
void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
var exceptionObj = args.ExceptionObject as Exception;
if (exceptionObj == null)
exceptionObj = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ args.ExceptionObject.ToString());
// TODO: Logging...
var messageBox = GetService<IMessageBoxService>();
messageBox.Show(
exceptionObj.Message,
"Unhandled exception.",
MessageBoxButton.OK,
MessageBoxImage.Exclamation);
Environment.Exit(1);
}
#region Resolve service dependencies members.
public TServiceContract GetService<TServiceContract>()
where TServiceContract : class
{
return ServiceContainer.Instance.GetService<TServiceContract>();
}
#endregion Resolve service dependencies members.
}
I want to use some code inside OnStartup (UnhandledException subscribing, injecting services), UnhandledExceptionHandler itself and GetService method in all my WPF applications without copy-pasting it by hands. What is the best way?
I have read a little about base class for App (derived from Application), but it seems that it has many drawbacks like problems with App.g.i.cs file (part of App class declaration), with XAML support (need to have App.xaml because Fluent's components don't want to work without adding reference to it through ResourceDictionary inside App.xaml), etc.
Upvotes: 1
Views: 276
Reputation: 7792
If you want to re-use code across projects (and especially across project types: wpf, winforms, console, web, etc), you might want to look into creating a separate class library project. These types of projects don't have a user interface/application: they are instead compiled to DLL files, which you can then reference in other .NET projects as you see fit.
Alternatively, within the same solution you can have multiple projects. It's not uncommon to have a number of projects with dependencies set up between them such that two different application projects within the same solution both use yet another class library project for a shared code base.
See below:
This is a typical web application project template that I use. The Domain project is at the bottom of the dependency chain, consisting of business objects that all other projects reference. The Data project contains data access code that other projects can access (except Domain). Web is the web application, and Services is a console application for server based utilities, etc. They both share the same Domain and Data (and a few other) projects.
In the case of the above, in my Web project I'd set a reference to the DomainServices project, then do something like this in my Web project:
using System;
using Template.DomainServices;
namespace Template.Web {
public class MyClass {
ILogger logger = new DomainServices.DefaultLogger();
public void Log(string msg) {
logger.Log(msg);
}
}
}
We're now using the logger implementation from the DomainServices shared project, calling it from the Web project, and we could do the same with any other project we wanted as well (granted, this is hardly the most technically-correct in terms of the code shown, but you get the idea?)
Perhaps that gives some ideas on how this can be approached?
One complication with deriving from the WPF base classes (or any application platform specific classes) is that your library classes are now tied to that particular application platform. In some cases this may be desireable, if the required functionality is specific to that platform. In other cases, such as loggers and such (and a great many other things), they can be just plain old C# objects (POCOs) that can be consumed by any application platform. The goal is typically to write platform-agnostic libraries except when there's specific need to target or extend a specific platform.
Upvotes: 2