Advanced Programming Tips 5 - PowerPoint PPT Presentation

1 / 22
About This Presentation
Title:

Advanced Programming Tips 5

Description:

You start with a pre-defined interface (say IPictureTransformer) which is the ... The host dynamically loads some assemblies (DLLs or EXEs) ... – PowerPoint PPT presentation

Number of Views:38
Avg rating:3.0/5.0
Slides: 23
Provided by: csR3
Category:

less

Transcript and Presenter's Notes

Title: Advanced Programming Tips 5


1
Advanced Programming Tips (5)
  • Plugins

2
Plugins are easy now, so well do NIMP the Net
Image Manipulation Program
  • You start with a pre-defined interface (say
    IPictureTransformer) which is the contract
    between the host and the plug-ins.
  • The host dynamically loads some assemblies (DLLs
    or EXEs),
  • It can inspect and see which types in the
    Assembly support the Interface, and instantiate
    them,
  • And then it can use them...

3
An Interface for NIMP plugins
using System using System.Drawing namespace
PlugIns public interface IPictureTransformer
string MenuCaption get
void Transform(Image im)
4
A plugin class which implements the interface,
and that we will load dynamically
public class ToGrey IPictureTransformer
public ToGrey() public string
MenuCaption get return Make it Grey"
public void Transform(System.Drawing.Image
im) Bitmap bm (Bitmap) im
for (int i 0 i lt bm.Height i)
for (int j 0 j lt bm.Width
j) Color p
bm.GetPixel(j, i) int g
(int) (255 p.GetBrightness())
bm.SetPixel(j, i, Color.FromArgb(255,g, g, g))

5
When the host initializes
void loadPlugIns() string
dllNames Directory.GetFiles(".", ".dll")
foreach (string fileName in dllNames)
string assm
Path.GetFileNameWithoutExtension(fileName)
string className "PlugIns." assm
try
IPictureTransformer theplugin
(IPictureTransformer)
AppDomain.CurrentDomain.CreateInstanceAndUnwrap

(assm, className)
//
if the object instantiation worked, we have a
plugin. // dynamically add it to the tools
menu addToToolsMenu(theplugin.
MenuCaption, theplugin)
catch // ignore this dll we
cannot instantiate a plugin here.
6
Notice how we extend the menu on the fly for each
plugin. The plugin itself supplies the caption.
void addToToolsMenu(string caption,
IPictureTransformer theplugin)
ToolStripMenuItem mi
new ToolStripMenuItem(caption, null, new
EventHandler(toolClicked)) mi.Tag
theplugin // save the instantiated object,
well call it later
toolsToolStripMenuItem.DropDownItems.Add(mi)
void toolClicked(object sender, EventArgs
e) ToolStripMenuItem mi
(ToolStripMenuItem)sender
IPictureTransformer thePlugIn
(IPictureTransformer) mi.Tag Image
im pictureBox1.Image
thePlugIn.Transform(im)
pictureBox1.Refresh()
7
Some notes
  • This works, but weve assumed only one plug-in
    per dll, and that its name is the same as the
    name of the dll. More sophistated options are
    available.
  • We test for the interface by instantiating and
    casting. Well it could be more elegant.
  • We keep the instantiated object alive in case the
    user requires its functionality. And we store it
    in the menus tag! ?

8
Observations
  • Any class supporting the right kind of interface
    can be used as a plug-in.
  • There is nothing special that you need to do in
    the hosted class.
  • Usually these classes implement some interfaces,
    and the host works via the interface rather than
    via some concrete type.
  • We need one statement in the host to load and
    instantiate a plug-in object.
  • Plug-in technology lets you open your core
    application to add-on extensions.

9
Observations 2
  • It is easy to write good apps and good modules
    in the small.
  • Its in the large that represents our 21CN
    challenges in CompSci.
  • The winners are going to be the guys who have
    better ways of tying together components.
  • Late binding loading plugins, is a potent tool
    for this.

10
The Holy Grail for Deployment
  • Web apps greatest advantage is that they can be
    centrally updated,
  • All issues of having old and new versions of apps
    in the field, with incompatibilities, disappear,
  • So a goal is to write Rich Applications that can
    update parts of themselves (like Acrobat or Media
    Player),
  • Interfaces and plug-in dlls get you quite far on
    this quest you can easily instant upgrade a
    product by providing plug-ins.
  • But 1-Click deployment may be an even better way
    to accomplish this. (1-Click doesnt open the
    market to outside providers creating the
    plug-ins.)

11
Just for fun Create new classes on the fly
  • It is even possible to create your own new
    assembly on the fly, emit some class definitions
    into the assembly (in MSIL intermediate code),
  • and then load and create the class instance and
    run it.
  • See the wild example under Help,
    CreateInstanceAndUnwrap and look at the crazy
    example they give for the first constructor

12
Creating new Classes on the fly could have a real
use
  • Algorithms needing very high-performance (e.g.
    DNA matching, looking up IP addresses against
    tables in a router or firewall, searching large
    datapools for regular expressions) can be made
    much more efficient if you generate a specific,
    specialized search for the data you currently
    have.
  • get the search parameters or search expression,
  • dynamically generate the MSIL opcodes (like the
    sample in the help file) to create a class that
    does only this search, but does it fast!
  • Load and run it. The Just-In-Time compiler
    (JIT) can take account of processor /
    architetural features, and even statistical info
    that is unavailable to traditional complier
    back-ends to produce very high performance native
    code.

13
Tracing and Debugging
  • The framework already provides
  • Debug and Trace classes with static members to
    Write, WriteLine, Flush, Close, etc.
  • These publish their output to listeners.
  • Listeners can be plugged in via the config file,
  • Some listeners (e.g. TextWriterTraceListener
    which writes to a file are already implemented.)

14
The client writes to Trace or Debug
using System.Diagnostics class myClass
public bool logon(string user)
Trace.WriteLine(Logon event for user )
  • All Trace/Debug objects are thread-safe.
  • Without configuration, they write to the console.
  • Debug output goes away when you compile for
    Release

15
You can plug in other existing listeners via a
new node at the bottom of the config file
ltconfigurationgt . ltsystem.diagnosticsgt
lttrace autoflushtruegt ltlistenersgt
ltadd name"myListener"
type"System.Diagnostics.TextWriterTraceListener"
initializeData"c\myLi
stener.log" /gt lt/listenersgt
lt/tracegt lt/system.diagnosticsgt lt/configurationgt
  • You can write and configure your own listener
    which sends trace data to a web service, or a
    database, or sends an SMS to the administrator.

16
The administrator can disable the default
listener too
  • ltlistenersgt
  • ltremove name"Default" /gt
  • lt/listenersgt

17
Filtering your output messages
  • Tracing and Debugging use 5 levels of severity,

18
Filtering Trace and Debug Output
  • You can create TraceSwitch objects to provide
    categories of tracing
  • TraceNetworking
  • TraceObjectCreation
  • TraceNewLogins
  • These automatically initialize their severity
    level from the configuration file,
  • Your code tests a switch and conditionally writes
    the trace/debug message,

19
The configuration file allows the administator to
initialize the switches
ltconfigurationgt ltsystem.diagnosticsgt ltswitchesgt
ltadd nameTraceNewLogin" value"3"
/gt lt/switchesgt lt/system.diagnosticsgt lt/config
urationgt
20
The code creates a switch instance and tests
against it
static TraceSwitch theSwitch new
TraceSwitch(TraceNewLogin", blah blah") //
severity level initialized from config file
public bool logon(string user) if
(theSwitch.TraceInfo)
Trace.WriteLine(Logon event for user)

21
Programming Tips
  • If youre going to need tracing, statistics, or
    debugging, and want to report errors back to some
    central collection,
  • And you want it to be easily configurable by the
    administrator,
  • Use the built-in Trace and Debug classes in
    System.Diagnostics.

22
Principles and generalizations
  • Components, deployments, and programs are relying
    more on flexible configuration options that are
    late bound
  • The general plug-in architecture for tracing and
    debugging allows an application to publish
    sophisticated diagnostic and tracing capabilities
    in an abstract way, with event categorization and
    verbosity settings
  • The admin can provide specialized listeners to
    hook your programs up to the local management
    systems
  • Programs that publish through Trace can use the
    same listeners to process data via the same
    management system (think NNOC).
  • For example if Nunit published test results to
    Trace, we could set a configuration in the daily
    build to plug in our own listener class. That
    could greatly simplify our processing of the
    results of the daily build. (Presently we use a
    DOS batch file that calls on grep to search
    through output text files! )
Write a Comment
User Comments (0)
About PowerShow.com