Übersetzung vorschlagen
 
Andere Vorschläge:

progress indicator
Keine anderen Vorschläge
MSDN Magazin > Home > Ausgaben > 2009 > MSDN Magazin August 2009 >  Erstellen von WPF und Silverlight-Anwendungen m...
Inhalt anzeigen:  Englisch mit deutscher ÜbersetzungInhalt anzeigen: Englisch mit deutscher Übersetzung
Dies sind maschinell übersetzte Inhalte, die von den Mitgliedern der Community bearbeitet werden können. Sie können die Übersetzung verbessern, indem Sie auf den jeweils zum Satz gehörenden Link "Bearbeiten" klicken.Mithilfe des Dropdown-Steuerelements "Inhalt anzeigen" links oben auf der Seite können Sie zudem bestimmen, ob nur der englische Originaltext, nur die deutsche Übersetzung oder beides nebeneinander angezeigt werden.
Inside Microsoft patterns & practices
Building WPF and Silverlight Applications with a Single Code Base Using Prism
Erwin van der Valk
Composite Application Guidance for WPF and Silverlight, also affectionately known as Prism v2, has been out for several months now. One of the areas Prism provides guidance on is the ability to target your application to both Windows Presentation Foundation (WPF) and Silverlight. It's interesting that, initially, this part of our guidance met quite a bit of resistance. Why were we focusing on multi-targeting for the first couple of iterations when we could be spending our time giving guidance on composition? But since the release of the Prism v2 project, we've found that a lot of our customers really love this part of the guidance. They especially like the Project Linker tool we built to help multi-targeting; as basic as it is, the tool has been well received and is being used in ways we couldn't have imagined.
So let's look at the approach we took for writing multi-targeted applications and how Prism can help you do the same.

Introduction
When we started work on Prism v2, in August 2008, we knew we wanted to support both WPF and Silverlight. Silverlight makes big strides toward closing the gap between the power of a rich-client application and the reach and ease of deployment of a Web application. The first version of Prism targets only WPF, but since WPF and Silverlight are very similar, we knew it wouldn't be too hard to create a Silverlight version. And since Prism helps in writing loosely coupled, modular applications, we felt that Prism could also help in allowing you to write applications that target both WPF and Silverlight from a single code base. The challenge is, of course, that although WPF and Silverlight are similar, they are not binary-compatible. The API and XAML language itself also has minor differences that make it harder to multi-target.
What Is Multi-Targeting and Why Should You Care?
Multi-targeting is the ability to target multiple platforms from a single code base. In this case, we are talking about targeting both the normal desktop version of the Microsoft .NET Framework version 3.5, which contains WPF and the Silverlight version of the .NET Framework.
So why should you care about this capability? The most obvious reason would be that you would like to take advantage of the strengths of WPF and Silverlight. In WPF, you can build applications that make full use of the client platform and interact with existing applications, such as Microsoft Office. It's also a lot easier to reuse existing assets, such as through COM interop or Windows Forms interop.
Whereas WPF gives you more capabilities, Silverlight gives you a much broader reach, because it runs on multiple platforms. It also runs in a protected sandbox, so end users can safely install Silverlight without needing administrative privileges. You don't need to completely multi-target your application to make it worthwhile. For example, you might expose small parts of internal applications over the Internet to give customers the ability to view and change some of their own information.

Creating a Silverlight Version of Prism
Even though we felt that multi-targeting would be a valuable capability for our customers, we also had a somewhat selfish reason for creating it. We wanted to build a Silverlight version of Prism, but we didn't want the overhead of maintaining two code bases. Because we didn't know how much code we would be able to reuse, we did a couple of spikes. A spike (in "agile" terminology) is a time-boxed exploration that allows you to learn more about a problem domain so that you can make a more valid estimation. So we did a couple of spikes to see how much of the Prism v1 code base we could migrate to Silverlight and how hard it would be to port our code to Silverlight. The conclusion was fascinating. We estimated that we could reuse around 80 percent of the code in the Prism library without modifying it.
Ideally, we would have liked to be able to create a single project and compile it to both WPF and Silverlight. The problem with that approach is that the project system in Visual Studio assumes that a project has one set of references, one compiler, and one type of output. We tried several ways of getting a single project to emit both Silverlight and WPF outputs, but none of them worked to our satisfaction.
One approach that worked really well was to create two projects and link files from one project to another. The nice thing about this approach is that you have fine-grained control over what each output should look like. For example, you can control which files should be shared or which assemblies should be referenced for each project. And any change to a linked file is immediately reflected in both projects.

Creating Project Linker
After our spiking phase, we agreed that the approach of linking files was working, although it was quite tedious and error-prone. We then had a lot of discussions: Should we invest a considerable amount of time in building a tool to help with multi-targeting, rather than spend that time creating guidance? It might not be obvious, but building and shipping a tool that integrates into Visual Studio is quite costly for us. Integrating with Visual Studio takes a bit of time in and of itself. Add to that the time it takes to build an installer that is signed according to the stringent Microsoft internal signing guidelines and to test the tool on many different environments. All of these factors reduce the amount of time we can spend on creating actual guidance. But because we felt quite strongly that this tool would help us in our efforts and be very helpful to our customers, we decided to go ahead and build it.
For the first couple of two-week iterations, we worked almost exclusively on Project Linker. As mentioned before, we received quite a bit of feedback from the community. Why were we spending time on multi-targeting? Wasn't Prism a project to help build composite applications? But while we were building Project Linker, we were also using it to create a Silverlight version of Prism. And because we were using Project Linker (internally, this is called dog-fooding, or eating your own dog food), we were confident our tool would be very usable.
We intentionally kept Project Linker very simple. It isn't magical in what it does, and anything you do using Project Linker can also easily be done manually. As the name implies, you can link two projects together as shown in Figure 1. Any file you add to the first project will be added as a linked file to the second project. Changes such as moving, renaming, or deleting would also be reflected.
Figure 1 Using the Project Linker to Link Files Between Projects
Because you might want to have control over which files to link, we implemented a simple naming convention. By default, all files except for those with a .xaml file name extension are linked. However, if you want to create files that are specific for a single platform, you can append the suffix .Desktop or .Silverlight to it. If you want, you can change this naming convention. In the project file, you'll find a regular expression that determines whether a file needs to be linked. The following is an example:
        ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?Silverlight  
           (\\.*)?$;\.desktop;\.Silverlight;\.xaml;^service references(\\.*)?$;\.  clientconfig;^web references(\\.*)?$"
Project Linker proved to be invaluable in creating Prism v2. After getting used to the minor quirks of this approach, which we'll go into later, it was such a pleasant experience to be able to write code once and have it compile to both a Silverlight and a WPF version. After awhile, project members had lists of extra features they would have liked Project Linker to have, but even without those features, the tool was very usable. The simplicity of the tool made it a lot more versatile than we had imagined. After it had been on CodePlex for a while, we heard from people that they weren't using it just to create Silverlight and WPF applications. Some people were also using it to link different Visual C++ projects together. Other people used it to have the same set of business validation rules running in a Silverlight application and in the Web services that the Silverlight application uses.

Test-Driven Development on Silverlight
Another area in which I've personally found multi-targeting to be handy is for doing test-driven development in Silverlight. I'm a big fan of test-driven development. Although there is an excellent unit test framework available for Silverlight, it has some shortcomings. It's not integrated with Visual Studio, and you can't select which test to run. It will run all the tests in your test assembly.
So now, even if I'm writing an application that will run only on Silverlight, I'll still create a linked WPF version of that project, just for writing and running the unit tests. I love having the ability to write a test and to then run it directly from Visual Studio. Within seconds, I'll have the result of my test, so the "code -> test -> fix -> test" cycles are very short. This really boosts my productivity. Just don't forget to run your Silverlight unit tests before you check in your code, because occasionally, a test will pass on one platform and fail on the other.

Architecting Your Application for Multi-Targeting
While building the Silverlight version of the Prism library, the Stock Trader Reference Implementation, and QuickStarts, we learned some valuable best practices regarding multi-targeting. The most important best practice is that a loosely coupled and modular architecture can really help your multi-targeting efforts. Loosely coupled architectures allow you to pick and choose which pieces of your application you would like to multi-target.

Identifying What Can Easily be Multi-Targeted
Before you can architect your solution to support multi-targeting, it's important to know what can and cannot easily be multi-targeted. In general, you can say that most business-logic-related code can very easily be multi-targeted. For example:
  • Presentation logic. This is the logic that responds to user actions and controls which data to pass to the visual elements.
  • Business logic and business rules. The business logic drives the business processes, and the business rules can perform validation on the business entities.
  • Business entities. These are classes that represent the data of your application.
Code that is more infrastructure-related is usually very hard to multi-target. The following are examples:
  • Visual elements (views). The way that you specify visual elements, such as controls, differs enough between WPF and Silverlight to make them hard to multi-target. Not only are different controls available for each platform, but the XAML that's used to specify the layout also has different capabilities. Although it's not impossible to multi-target very simple views or some simple styling, you'll quickly run into limitations.
  • Configuration settings. Silverlight does not include the System.Configuration namespace and has no support for configuration files. If you want to make your Silverlight application configurable, you'll need to build a custom solution.
  • Data access. The only way a Silverlight application can have access through data is through Web services. Unlike WPF, a Silverlight application cannot directly access databases.
  • Interop (with other applications, COM, or Windows Forms). A WPF application in a full-trust environment can interact with other applications on your computer or use existing assets such as COM or Windows Forms objects. This is not possible in Silverlight, because it runs in a protected sandbox.
  • Logging and tracing. Because of the protected sandbox, a Silverlight application cannot write log information to the EventLog or trace information to a file (other than in isolated storage).
In order to design an application that allows you to easily reuse your business logic, you should try to separate things that are easy to multi-target from things that are hard to multi-target. Interestingly enough, this is exactly the architecture of a typical Prism application. Figure 2 shows the typical architecture of a Prism application.
Figure 2 Typical Prism Application Architecture
In this diagram, the views are classes that perform the visualization aspect of your application. Typically, these are controls and pages, and in the case of WPF or Silverlight applications, they often define the layout in XAML. The logic of your application is factored out into separate classes. I'll dive a bit more into the design patterns behind this when I talk about separated presentation patterns.
The application services in this diagram can provide a wide variety of functionality. For example, a Logger or a Data Access component can be considered an application service. Prism also offers a couple of these services, such as the RegionManager or the XapModuleTypeLoader. I'll discuss these services more when I talk about building platform-specific services.

Separated Presentation
As part of the guidance that we provide with Prism, we recommend that you separate the visualization aspect of your application from the presentation logic. A lot of design patterns, such as Model-View-ViewModel or Model-View-Presenter, can help you with this. What most of these patterns have in common is that they describe how to split up your user-interface-related code (and markup) into separate classes, each with distinct responsibilities. Figure 3 shows an example of the Model-View-ViewModel pattern.
Figure 3 Example of Model-View-ViewModel Pattern
The Model class has the code to contain and access data. The View is usually a control that has code (preferably in the form of XAML markup) that visualizes some of the data in your model and ViewModel. And then there is a class named either ViewModel, PresentationModel, or Presenter that will hold as much of the UI logic as possible. Typically, a separated presentation pattern is implemented to make as much of your UI-related code unit testable as possible. Because the code in your views is notoriously hard to unit test, these separated presentation patterns help you place as much of the code as possible in a testable ViewModel class. Ideally, you would not have any code in your views, just some XAML markup that defines the visual aspects of your application and some binding expressions to display data from your ViewModel and Model.
When it comes to multi-targeting, a separated presentation pattern has another significant advantage. It allows you to reuse all of your UI logic, because you have factored out that logic into separate classes. Although it's not impossible to multi-target some of the code in your views (the XAML, controls, and code-behind), we've found that the differences between WPF and Silverlight are big enough that multi-targeting your XAML is not practical. XAML has different abilities, and the controls that are available for WPF and Silverlight are not the same. This not only affects the XAML, but it also affects the code-behind.
Although it's not likely that you are able to reuse all of your UI-related code, a separated presentation pattern helps you reuse as much of the presentation logic as possible.

Building Platform-Specific Services
While building the Prism libraries and the Stock Trader Reference Implementation, we strictly followed the single-responsibility principle. This principle describes that each class should have only one reason to change. If a class addresses multiple concerns or has more than one responsibility, it has multiple reasons to change. For example, a class that can load a report from a database and print that report can change if the database changes or if the layout of the report changes. An interesting indication if your class does too much: if you find that you have difficulty determining a name for your class that describes its responsibility, it has too many responsibilities.
If you follow the single-responsibility principle, you'll often end up with a lot of smaller classes, each with its own discrete responsibility and a descriptive name. We often consider many of these classes to be application services, because they provide a service to your application.
This single-responsibility principle really helps when it comes to multi-targeting. Take, for example, the module loading process in Prism. A lot of aspects of this process are similar for both WPF and Silverlight. Some similarities include how the ModuleCatalog keeps track of which modules are present in the system and how the ModuleInitializer creates the module instances and calls the IModule.Initialize() method on them. But then again, how we are loading the assembly files that contain the modules differs quite a bit between WPF and Silverlight. Figure 4 illustrates this.
Figure 4 Module Loading in Prism
It's perfectly reasonable for a WPF application to load its modules from disk. So this is what the FileModuleTypeLoader does. However, this doesn't make sense for a Silverlight application, because its protected sandbox doesn't give access to the file system. But for Silverlight, you'll need a XapModuleTypeLoader to load modules from a .xap file.
Because we created smaller classes, each with a distinct responsibility, it was a lot easier to reuse most of these classes and create only platform-specific services to encapsulate the behavior that differs between the platforms.

Avoid Inconsistencies and Try to Keep a Single Code Base
Even though most functionality in Prism was easily ported to Silverlight, we inevitably ran into situations where we would rely on a feature in WPF that didn't exist in Silverlight. Dependency property inheritance was one of them. In WPF, you could set a dependency property on a control and it would automatically be inherited by any of its children. We were using this capability to associate a region with a region manager. Unfortunately, automatic property inheritance is not available in Silverlight.
For Silverlight, we had to create a solution that delayed the creation of regions until the region manager could be located through some other mechanism. With a couple of tweaks, we could reuse this code for WPF. We could have kept the original, much simpler solution for WPF and used only the new solution for Silverlight, but then we would have had to maintain two code bases and offer a different public API.
When trying to build a functionality for use in both WPF and Silverlight, you'll inevitably run into situations where one of the platforms doesn't support a feature that you want to use. Your best defense against these situations is to try to work around these "incompatibilities" and create a solution that works in both environments. Maintaining a single code base is a lot easier than maintaining two code bases!

Accommodate for Different Platform Capabilities
There are cases where it doesn't make sense or isn't possible to work around platform differences, such as when there is no common solution that would work in both WPF and Silverlight. When this happens, there are a couple of strategies to consider. For anything but small and isolated platform differences, I would recommend building platform-specific services. But for small platform differences, you could consider either conditional compilation or partial classes.

Conditional Compilation
The simplest thing to do to accommodate for different platform capabilities is to use conditional compilation. By using the #if SILVERLIGHT pre-compiler statement, shown in Figure 5, you can create sections of code that are compiled only into Silverlight or only into WPF. This seems very handy, but a method or class can quickly become unreadable with this approach.
#if SILVERLIGHT
            Application.Current.RootVisual = shell;
#else
            shell.Show();
#endif
We've found that you should use the #if pre-compiler directive only to sporadically change a single line of code. Because readability really suffers, I don't recommend using this technique for anything but very simple cases like this.

Partial Classes
Another technique you could employ is the usage of partial classes. Using this technique, you can create classes that are mostly shared, but differ in one or two small methods. This technique can be very useful for adjusting small implementation changes between WPF and Silverlight.
I find partial classes to be particularly useful in the area of exceptions. In the .NET Framework, it's often recommended to make your exceptions serializable. However, Silverlight doesn't support the [Serializable] attribute. Using partial classes, you can reuse most of the exception code, but you can apply the [Serializable] attribute only on the .NET Framework variant of the code as shown in Figure 6.
// MyException.cs
Public partial class MyException : Exception
{
   . . .
}

// Desktop only additions to this class. 
// MyException.Desktop.cs
[Serializable]
Public partial class MyException : Exception
{
    protected  MyException (SerializationInfo info, StreamingContext context) : base(info, context) { }
}
Unfortunately, partial classes do suffer from discoverability and readability issues. It's not immediately clear in which file your functionality resides. A class should have a single responsibility and be named to reflect that single responsibility. If you find that a class does something in one way in Silverlight and another in WPF, it's not following the single-responsibility pattern. Extracting the platform-specific code into services with a descriptive name is usually a better solution.

Because Visual Studio was never designed to accommodate multi-targeting, you will likely run into some quirks that are caused by the approach. None of them are very serious, but it helps to know what they are.
Visual Studio knows that a linked file can be placed in different types of projects. So, depending on whether you open the linked file from WPF or Silverlight, it will adapt the IntelliSense accordingly. It's often possible that you use a language construct that is available in only one of the platforms. You will encounter build errors when compiling your solution because your code is invalid for one of the platforms. Depending on whether you opened the file from WPF or Silverlight will determine whether you will see the red squiggly. But once you grow accustomed to the fact that a change in one project can break its linked project, you'll quickly know where to look.
Project references are also interesting. Project Linker doesn't automatically add references. We looked into this while building the tool, but there were too many edge cases to make this reliable. For example, the binaries for Silverlight have different names than the binaries for WPF.
Lastly, you can link almost any type of file, such as resource files. However, you should make sure that the properties, such as the compilation options, are the same between both projects.

Many of our customers absolutely love Prism. Even if your application doesn't need the composite capabilities that Prism offers, it can still benefit tremendously from the flexible architecture that Prism promotes. The ability to easily multi-target your application is just one of those benefits—and it's a really nice one! You can download the binary and source code files for Project Linker from the Microsoft Download Center. You can learn more about Prism online .

Erwin Van der Valk is a developer on Microsoft ’s patterns and practices team. He is also a scuba diver, a kung fu master, and a metal guitarist. Give him some code—he’ll dive right in, kicking and screaming, and will make a lot of noise while doing it! Check out the noise he makes at erwinvandervalk. net .

Inside Microsoft Patterns & practices
Erstellen von WPF und Silverlight-Anwendungen mit einer einzelnen Codebasis mit prism
Erwin van der Valk
Composite Application Anleitungen für WPF und Silverlight, auch liebevoll als Prism v2 bezeichnet wurde, jetzt mehrere Monate. Eines der Prism auf Anleitung bietet Bereiche ist die Möglichkeit, Ihre Anwendung Windows Presentation Foundation (WPF) und Silverlight als Ziel. Es ist, die anfänglich interessant, diesen Teil unserer Anleitung erfüllt etwas Widerstand. Warum wurden wir Schwerpunkt auf der ersten Reihe von Iterationen Multi Zielgruppenadressierung Wenn wir unsere Zeit erteilen Anleitungen auf Komposition Ausgaben werden konnte? Aber seit der Veröffentlichung des Projekts v2 Prism haben wir gefunden, dass viele Kunden wirklich diesem Teil der Anleitung Liebe. Insbesondere wie Sie das Projekt Linker-Tool wir damit Multi-Zielgruppenadressierung erstellt; als grundlegende ist, das Tool auch empfangen wurden und Möglichkeiten haben wir vorstellen, konnte nicht verwendet wird.
So betrachten wir Ansatz beim Schreiben von Multi abzielende Anwendungen und wie Prism dasselbe beitragen kann.

Einführung
Wenn wir arbeiten auf Prism v2 im August 2008 gestartet, wusste wir, wir wollten, WPF und Silverlight unterstützen. Silverlight stellt große Fortschritte in Richtung schließen die Lücke zwischen der Leistungsfähigkeit eine Rich Client-Anwendung und die Reichweite und Einfachheit der Bereitstellung einer Webanwendung. Die erste Version des Prism nur WPF zielt, aber da WPF und Silverlight sehr ähnlich sind, wir wussten es Erstellen einer Silverlight-Version zu schwierig wäre. Und da Prism hilft beim Schreiben, modulare Anwendungen lose wir Gefühl, dass Prism auch Hilfe konnte in Sie Schreiben von Anwendungen, die aus einer einzelnen Code Basis WPF und Silverlight als Ziel. Die Herausforderung ist natürlich, obwohl WPF und Silverlight ähnlich sind, nicht binär-kompatibel sind. Die API und XAML-Sprache selbst verfügt auch geringfügige Unterschiede, die zu Multi-target erschweren.
Was ist die Multi-Zielgruppenadressierung und warum Care ShouldYou?
Mehrere Zielgruppenadressierung ist die Möglichkeit für mehrere Zielplattformen aus einer einzelnen Codebasis. In diesem Fall sind wir sprechen zum Erfassen der normalen Desktopversion von Microsoft .NET Framework Version 3.5, WPF enthält und die Silverlight-Version von der .NET Framework.
Daher sollten warum Sie diese Funktion kümmern? Die offensichtliche Ursache wäre, dass Sie die Stärken von WPF und Silverlight nutzen möchten. In WPF können Sie Anwendungen, die die Clientplattform voll nutzen und interagieren mit vorhandenen Anwendungen wie Microsoft Office erstellen. Leichter auch viel vorhandene Ressourcen, z. B. über COM-Interop oder Windows Forms Interop wiederverwenden.
Während WPF Ihnen mehr Möglichkeiten bietet, Ihnen Silverlight eine viel breitere Reichweite da er auf mehreren Plattformen ausgeführt wird. Es wird auch in einer geschützten Sandbox ausgeführt, sodass Endbenutzer sicher Silverlight ohne Administratorrechte installieren können. Müssen Sie nicht zu vollständig multi-target Ihrer Anwendung sinnvoll. Sie können z. B. kleine Teile des internen Anwendungen ausgesetzt, über das Internet an Kunden haben die Möglichkeit, anzeigen und ändern einige eigene Informationen.

Erstellen einer Silverlight-Version von prism
Obwohl wir das Gefühl, Multi-Zielgruppenadressierung eine nützliche Funktion für unsere Kunden wäre, mussten wir auch einen etwas selfish Grund für Sie erstellen. Wir eine Silverlight-Version von Prism erstellen möchten, aber wir haben den Overhead von zwei Codebasen verwalten möchten. Da wir wissen nicht, wie viel Code wiederverwenden werden würde, haben wir eine Reihe von Spitzen. Eine Sammlung (in der Terminologie "agile") ist eine Zeit geschachtelt Untersuchung, die einer Problemdomäne erfahren so dass Sie eine weitere gültige Vorkalkulation können ermöglicht. Daher haben wir eine Reihe von Spitzen, um anzuzeigen, wie viel der Prism v1 CodeBase wir migrieren konnte Silverlight und wie schwierig wäre unser Code nach Silverlight portieren. Die Schlussfolgerung war faszinierend. Wir geschätzt, dass wir ungefähr 80 Prozent des Codes in der Prism-Bibliothek wiederverwenden konnte, ohne es zu ändern.
Im Idealfall würden haben wir zusagt um ein einzelnes Projekt erstellen und kompilieren Sie es in WPF und Silverlight zu können. Das Problem bei diesem Ansatz ist, dass das Projektsystem in Visual Studio davon ausgegangen wird, dass ein Projekt eine Verweise, einen Compiler und einen Typ der Ausgabe verfügt. Wir haben versucht, mehrere Möglichkeiten erhalten ein einzelnes Projekt Ausgeben von Silverlight und WPF-Ausgaben, aber keines davon zu unserer Zufriedenheit gearbeitet.
Eine Möglichkeit, das wirklich gut funktionierte war die zwei Projekte erstellen und Verknüpfen von Dateien aus einem Projekt zu einem anderen. Nettes Vorteil dieses Ansatzes ist, dass Sie präzise steuern, über welche jeder Ausgabe aussehen sollte. Sie können beispielsweise steuern, welche Dateien freigegeben werden soll oder welche Assemblys für jedes Projekt verwiesen werden soll. Und jede Änderung an einer verknüpften Datei ist in beiden Projekten sofort wiedergegeben.

Erstellen von Project-Linker
Nach unserer spiking Phase vereinbarten wir Obwohl es ziemlich mühsam und fehleranfällig war, dass der Ansatz, Verknüpfen von Dateien gearbeitet wurde. Dann mussten wir viel Diskussionen: sollten wir sehr viel Zeit erstellen Sie ein Tool zur Hilfe bei Multi-Zielgruppenadressierung, anstatt die Anleitung erstellen Zeit investieren? Möglicherweise nicht offensichtlich, aber erstellen und liefern ein Tool, das in Visual Studio integriert ist für uns recht teuer macht. Integration von mit Visual Studio dauert ein wenig Zeit in und von sich selbst. Fügen Sie hinzu, die es dauert um ein Installationsprogramm erstellen, die entsprechend in der strengen Microsoft internen Richtlinien Signatur signiert ist und das Tool auf vielen verschiedenen Umgebungen zu testen. All diese Faktoren reduzieren Sie die Zeit, die wir investieren können zum Erstellen von tatsächlichen Anleitungen. Aber da das wir ziemlich stark Gefühl, dass dieses Tool helfen Sie uns in unsere Bemühungen und sehr hilfreich, unsere Kunden sein würden, wir entschieden, fortfahren und erstellt.
Für die ersten Paar von zwei Wochen Iterationen wir fast ausschließlich an Linker Projekt gearbeitet. Wie bereits erwähnt, können wir etwas Feedback von der Community erhalten. Warum wurden wir immer auf Multi-Zielgruppenadressierung Ausgaben? Wasn't Prism ein Projekt zum Erstellen zusammengesetzter Anwendungen helfen? Aber während wir Project Linker erstellt wurden, wir wurden auch dessen Verwendung zum Erstellen einer Silverlight-Version der Prism. Und da wir waren Project Linker (intern wird Hund Fooding aufgerufen oder Essen Ihre eigenen Hund Essen) verwenden wir waren sicher unsere Tools sehr verwendbar sein würde.
Wir absichtlich Project Linker sehr einfach gehalten. Es ist nicht in Funktionsweise magischen und etwas tun werden mit Project Linker kann auch problemlos manuell durchgeführt werden. Wie der Name schon sagt, können Sie zwei Projekte wie in Abbildung 1 gezeigt miteinander verknüpfen. Sie dem ersten Projekt hinzufügen Dateien werden als verknüpfte Datei auf das zweite Projekt hinzugefügt. Ändert z. wie verschieben, umbenennen oder löschen auch übernommen werden.
Abbildung 1 mit den Linker Project Verknüpfen von Dateien zwischen Projekte
Da Sie möglicherweise steuern welche Dateien verknüpfen möchten, implementiert haben wir eine einfache Benennungskonvention. In der Standardeinstellung sind alle Dateien außer mit der Erweiterung .XAML verknüpft. Wenn Sie möchten Dateien erstellen, die für eine einzelne Plattform spezifisch sind, können das Suffix .Desktop oder .Silverlight an ihn anfügen werden. Wenn Sie möchten, können Sie diese Benennungskonvention ändern. In der Projektdatei finden Sie einen regulären Ausdruck, der bestimmt, ob eine Datei verknüpft werden muss. Das folgende Beispiel verdeutlicht dies:
        ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?Silverlight  
           (\\.*)?$;\.desktop;\.Silverlight;\.xaml;^service references(\\.*)?$;\.  clientconfig;^web references(\\.*)?$"
Projekt Linker erwies als bei Prism v2 erstellt werden. Nach dem Abrufen verwendet um geringfügigen Marotten dieses Ansatzes besteht, die wir in einem späteren Zeitpunkt zu war eine erfreulich Erfahrung in der Lage Code einmal schreiben und es sowohl für ein Silverlight eine WPF-Version zu kompilieren. Nach eine gewisse Zeit Projektmitglieder hatte Listen mit zusätzlichen Features, die Sie Project Linker, zusagt haben würde, aber auch ohne diese Features wurde das Tool sehr verwendbar. Die Einfachheit des Tools war es viel flexibler als wir hätten vorstellen. Nach auf CodePlex für eine Weile hatte, hören wir von Personen, dass Sie es einfach zum Erstellen von Silverlight und WPF-Anwendungen verwenden wurden nicht. Einige Personen wurden auch es verwenden, um verschiedene Visual C++-Projekte miteinander verknüpfen. Andere verwendete er denselben Satz von Geschäftsregeln der Gültigkeitsprüfung in einer Silverlight-Anwendung und in die Webdienste, die die Silverlight-Anwendung verwendet.

Test-Driven Development für Silverlight
Ein weiterer Bereich, persönlich praktisch sein Multi Zielgruppenadressierung gefundenen, ist dafür der testgesteuerten Entwicklung in Silverlight. Ich bin ein großer Fan der testgesteuerten Entwicklung. Es ist eine hervorragende Framework verfügbar für Silverlight Komponententest, hat aber einige Nachteile. Ist nicht mit Visual Studio integriert, und Sie können nicht auswählen, testen, führen. Es werden alle Tests in Ihrer Testassembly ausgeführt.
So nun, selbst wenn ich eine Anwendung schreiben werde, die nur auf Silverlight ausgeführt werden, ich noch eine verknüpfte WPF-Version dieses Projekts nur zum Schreiben und Ausführen die Komponententests erstellen. Ich liebe die Möglichkeit, einen Test schreiben und anschließend direkt aus Visual Studio ausführen müssen. Innerhalb von Sekunden müssen ich das Ergebnis meiner Tests, die Zyklen "-> Test-> Update-> Test code" sehr kurz. Dies erhöht wirklich meine Produktivität. Nur vergessen Sie nicht Ihre Silverlight-Komponententests ausführen, bevor Sie in Ihrem Code, prüfen da manchmal ein Test auf einer Plattform übergeben und auf den anderen fehlschlagen.

Architektur der Anwendung mehrere Zielgruppenadressierung
Beim Erstellen der Silverlight-Version der Prism-Bibliothek, vordefinierten Traders Referenzimplementierung und Schnellstarts, haben wir einige wichtige Empfehlungen bezüglich der Multi-Zielgruppenadressierung. Die wichtigste optimale Methode besteht, dass eine lose gekoppelte und modulare Architektur Ihre Bemühungen Multi-Zielgruppenadressierung wirklich helfen kann. Lose gekoppelte Architekturen können Sie und Auswählen der Teile der Anwendung Multi-target sollen.

Was kann einfach identifiziert werden mehrere angestrebte
Bevor Sie Ihre Lösung zur Unterstützung von Multi-Zielgruppenadressierung Architekt können, ist es wichtig zu wissen, was können und nicht einfach Multi-Ziel. Im Allgemeinen können Sie sagen, dass die meisten Logik-geschäftsbezogene Code sehr einfach Multi gerichtet werden kann. Beispiel:
  • Präsentationslogik. Dies ist die Logik, die auf Benutzeraktionen reagiert und steuert, welche Daten an die visuellen Elemente übergeben.
  • Geschäftslogik und Geschäftsregeln. Die Geschäftslogik Laufwerke von Geschäftsprozessen, und die Geschäftsregeln können Überprüfung auf die Geschäftsentitäten durchführen.
  • Geschäftsentitäten. Diese sind Klassen, die die Daten der Anwendung darstellen.
Code, der mehr Infrastruktur-bezogene ist, ist normalerweise sehr schwer zu Multi-target. Im folgenden werden Beispiele:
  • visuelle Elemente (Ansichten). Die Möglichkeit,, visuelle Elemente wie Steuerelemente anzugeben, genug unterscheidet zwischen WPF und Silverlight schwierig zu Multi-target machen. Nicht nur stehen verschiedene Steuerelemente für jede Plattform, jedoch das XAML, die zum Angeben des Layouts verwendet, auch weist verschiedene Fähigkeiten. Obwohl es nicht unmöglich, multi-target sehr einfache Ansichten oder einige einfache Stile, werden Sie schnell in Einschränkungen ausführen.
  • Konfiguration Einstellungen. Silverlight enthält keinen System.Configuration-Namespace und bietet keine Unterstützung für Konfigurationsdateien. Wenn Sie die Silverlight-Anwendung konfigurierbar machen möchten, müssen Sie eine benutzerdefinierte Lösung erstellen.
  • Daten zugreifen. Die einzige Möglichkeit, die eine Silverlight-Anwendung durch die Daten zugreifen kann, ist über Webdienste. Im Gegensatz zu WPF kann keine Silverlight-Anwendung direkt auf Datenbanken zugreifen.
  • -Interop (mit anderen Anwendungen, COM oder Windows Forms). Eine WPF-Anwendung in einer Umgebung mit voller Vertrauenswürdigkeit kann mit anderen Anwendungen auf Ihrem Computer interagieren oder vorhandene Ressourcen wie z. B. COM oder Windows Forms-Objekte verwendet werden. Dies ist nicht in Silverlight möglich, da er in einer geschützten Sandbox ausgeführt wird.
  • Protokollierung und Ablaufverfolgung. Aufgrund der geschützten Sandbox kann keine Silverlight-Anwendung Protokollinformationen in der EventLog oder Ablaufverfolgung Informationen in einer Datei (außer im isolierten Speicher) schreiben.
Um eine Anwendung entwerfen, die Sie Ihre Geschäftslogik problemlos wiederverwenden können, sollten Sie die Dinge zu trennen, die einfach zu Multi-target von Dinge sind, die schwer zu Multi-target sind. Interessanterweise ist dies genau die Architektur einer typischen Anwendung Prism. Abbildung 2 zeigt die typische Architektur einer Anwendung Prism.
Abbildung 2 typische Prism Anwendungsarchitektur
In diesem Diagramm sind die Ansichten Klassen, die den Visualisierung Aspekt Ihrer Anwendung durchführen. In der Regel diese Steuerelemente und Seiten, und im Fall von WPF oder Silverlight-Anwendungen Sie häufig definieren das Layout in XAML. Die Logik der Anwendung ist, in separate Klassen berücksichtigt. Ich werde ich über getrennte Präsentation Muster sprechen etwas in die Entwurfsmuster hinter diesem eintauchen.
Die Anwendungsdienste in diesem Diagramm können eine Vielzahl von Funktionen bereitstellen. Beispielsweise kann eine Protokollierung oder eine Datenzugriffs-Komponente ein Anwendungsdienst betrachtet werden. PRISM bietet auch eine Reihe von diese Dienste wie die RegionManager oder die XapModuleTypeLoader. Diese Dienste erörtert mehr Wenn ich zum Plattform-spezifische Dienste erstellen sprechen.

Getrennte Präsentation
Als Teil der Anleitung, die wir mit Prism bereitstellen, empfehlen wir, dass Sie den Visualisierung Aspekt Ihrer Anwendung die Darstellungslogik trennen. Viel Entwurfsmuster wie Model-View-ViewModel oder Model-View-Presenter kann Ihnen dabei helfen. Was die meisten dieser Muster haben gemeinsam, dass Sie Ihre Benutzer-Schnittstelle-bezogenen Code (und Markup) in separate Klassen mit unterschiedlichen Zuständigkeiten aufzuteilen beschrieben wird. Abbildung 3 zeigt ein Beispiel für die Model-View-ViewModel-Muster.
Abbildung 3 Beispiel für die Model-View-ViewModel-Muster
Die Model-Klasse hat den Code enthalten und auf Daten zugreifen. Die Ansicht ist normalerweise ein Steuerelement mit Code (vorzugsweise in Form eines XAML-Markup), die Teil der Daten in Ihrem Modell und ViewModel anhand seiner bildlichen Vorstellungen. Und besteht eine Klasse namens ViewModel, PresentationModel oder Vortragenden, die Teil der Benutzeroberflächenlogik wie möglich halten wird. In der Regel ist ein getrennter Präsentation Muster implementiert, zu wie viel Ihre Benutzeroberfläche bezogenen Codeeinheit getestet wie möglich. Da der Code in Ihre Ansichten Komponententest offenkundig schwer ist, getrennt diese Präsentation Muster Hilfe, die Sie so viel von der Code wie möglich in einer testbare ViewModel-Klasse setzen. Im Idealfall müssten nicht Sie Code in Ihre Ansichten nur einige XAML-Markup, das die visuellen Aspekte der Anwendung definiert und einige Bindungsausdrücke, um Daten aus der ViewModel und Modell anzuzeigen.
Bei Multi-Zielgruppenadressierung, hat eine getrennte Präsentation Muster ein anderes erhebliche Vorteile. Es können Sie alle Ihre Benutzeroberflächenlogik wiederverwenden da Sie die Logik in separate Klassen angepasst haben. Zwar nicht unmöglich, Multi-target einige der Code in Ihre Ansichten (XAML, Steuerelemente und Code-Behind), wir haben befinden, die Unterschiede zwischen WPF- und Silverlight groß genug, dass Multi-targeting XAML ist nicht sinnvoll. XAML weist verschiedene Fähigkeiten und die Steuerelemente, die für WPF und Silverlight zur Verfügung stehen sind nicht identisch. Dies betrifft nicht nur das XAML, aber es betrifft auch der Code-Behind.
Obwohl es nicht wahrscheinlich, dass Sie alle Benutzeroberfläche bezogenen Code wiederverwenden können, kann ein getrennter Präsentation Muster Sie viel von der Darstellungslogik wie möglich wiederverwenden.

Plattform-spezifischer Entwickeln von Webdiensten
Beim Erstellen der Prism-Bibliotheken und der vordefinierten Traders Referenzimplementierung, folgen wir ausschließlich das Prinzip der einzigen Verantwortung. Dieses Prinzip beschrieben, dass jede Klasse nur ein Grund zum ändern sollten. Eine Klasse behebt mehrere Probleme oder mehrere verantwortlich ist, hat mehrere Gründe, zu ändern. Beispielsweise kann eine Klasse, die einen Bericht aus einer Datenbank laden und Drucken dieses Berichts kann, ändern, wenn die Datenbank ändert oder wenn das Layout des Berichts ändert. Ein interessantes Hinweis Wenn Ihre Klasse zu viel: Wenn Sie feststellen, dass Sie bestimmen einen Namen für die Klasse, die die Verantwortung beschreibt Schwierigkeiten haben, hat es zu viele Aufgaben.
Wenn Sie das Prinzip der einzigen Verantwortung folgen, werden Sie häufig mit jeweils eigenen diskrete Verantwortung und einen beschreibenden Namen viel kleinere Klassen beenden. Wir betrachten häufig viele dieser Klassen, Anwendungsdienste, da Sie einen Dienst für Ihre Anwendung bieten.
Dieses Prinzip der einzigen Verantwortung trägt wirklich bei Multi-Zielgruppenadressierung. Nehmen Sie zum Beispiel das Modul Ladeprozess im Prism. Zahlreiche Aspekte von diesem Prozess sind für WPF und Silverlight ähnlich. Einige Ähnlichkeiten enthalten wie die ModuleCatalog hält Verfolgen der Module in das System und wie die ModuleInitializer Modul Instanzen erstellt werden und ruft die IModule.Initialize()-Methode auf. Aber dann again, wie wir die Assemblydateien geladen werden, die die Module enthalten zwischen WPF und Silverlight ziemlich etwas unterscheidet. Abbildung 4 veranschaulicht dies.
Abbildung 4 in Prism laden
Es ist durchaus sinnvoll für eine WPF-Anwendung die Module von Datenträger laden. So ist dies die Funktionsweise der FileModuleTypeLoader. Dies durchführen nicht jedoch sinnvoll sein, eine Silverlight-Anwendung, da seine geschützten geschützten Zugriff auf das Dateisystem gewähren nicht. Doch für Silverlight, müssen Sie eine XapModuleTypeLoader um Module aus einem XAP-Datei zu laden.
Da wir kleinere Klassen mit einer distinct Verantwortung erstellt war es viel einfacher zu verwenden die meisten dieser Klassen und erstellen Sie nur die plattformspezifischen Dienste das Verhalten zu kapseln, das zwischen den Plattformen unterscheidet.

Vermeiden von Abweichungen und versuchen, eine einzelne Codebasis beibehalten
Obwohl die meisten Funktionen in Prism problemlos auf Silverlight portiert wurde, haben wir unvermeidlich in Situationen, in denen wir auf ein Feature in WPF verlassen würde, die in Silverlight vorhanden sind, nicht, ausgeführt. Eigenschaftenvererbung Abhängigkeit war eine davon. In WPF Sie können eine Abhängigkeitseigenschaft für ein Steuerelement festlegen, und würden automatisch von allen untergeordneten geerbt werden. Wir wurden diese Funktion verwenden, um ein Manager Region eine Region zugeordnet. Automatische Eigenschaftenvererbung ist leider nicht verfügbar in Silverlight.
Für Silverlight musste eine Lösung erstellen, die die Erstellung von Bereichen verzögert, bis der Region-Manager durch einen anderen Mechanismus gefunden werden konnte. Mit wenigen Anpassungen konnte wir diesen Code für WPF wiederverwenden. Wir konnte die ursprüngliche, viel einfacher Lösung für WPF gespeichert haben und nur die neue Lösung für Silverlight verwendet, aber dann wir würden mussten zwei Codebasen verwalten und eine andere öffentliche API anbieten.
Beim Versuch, eine Funktion für die Verwendung in WPF und Silverlight zu erstellen, müssen Sie zwangsläufig in Situationen ausführen nicht eine der Plattformen ein Feature unterstützt, die Sie verwenden möchten. Ihre beste Verteidigung gegen diesen Situationen besteht darin, diese "Inkompatibilitäten" zu umgehen und eine Lösung, die funktioniert in beiden Umgebungen erstellen. Verwaltet eine einzige Codebasis viel einfacher als das Verwalten von zwei Code baut!

Für andere Plattform Funktionen aufzunehmen
Es gibt Fälle, in dem es keinen Sinn oder ist nicht möglich Plattform Unterschiede, z. B. umgehen, wird es keine allgemeine Lösung, die in WPF und Silverlight funktionieren würde. Wenn dies geschieht, sind einige Strategien zu berücksichtigen. Für beliebig jedoch klein und isolierten Plattform Unterschiede empfehle ich plattformspezifische Dienste erstellen. Jedoch für kleine Plattform Unterschiede Sie in Betracht konnte ziehen oder die bedingte Kompilierung als auch die partielle Klassen.

Bedingte Kompilierung
Die einfachste Vorgehensweise um unterschiedliche Plattformfunktionen aufnehmen zu können, ist die bedingten Kompilierung Verwendung. Mithilfe der # If SILVERLIGHT pre-compiler Anweisung, dargestellt in Abbildung 5 können Sie Abschnitte des Codes erstellen, die nur in Silverlight oder nur in WPF kompiliert werden. Dies scheint sehr nützlich, aber eine Methode oder Klasse kann schnell unlesbar bei diesem Ansatz.
#if SILVERLIGHT
            Application.Current.RootVisual = shell;
#else
            shell.Show();
#endif
Wir haben festgestellt, dass Sie die pre-compiler # If-Direktive verwenden sollten, nur um eine einzelne Codezeile sporadisch zu ändern. Da Lesbarkeit wirklich leidet, empfehle nicht ich diese Technik für beliebig aber sehr einfachen Fällen sieht.

Partielle Klassen
Ein weiteres Verfahren, das Sie einsetzen konnte, ist die Verwendung von partiellen Klassen. Mit diesem Verfahren können Sie Klassen, die hauptsächlich freigegeben sind, jedoch unterscheiden sich erstellen, in einem oder zwei kleinen Methoden. Dieses Verfahren kann zum Anpassen von kleinen Implementierung Änderungen zwischen WPF und Silverlight sehr nützlich sein.
Ich finde partielle Klassen in den Bereich der Ausnahmen besonders nützlich sein. In .NET Framework empfiehlt es oft um Ihre Ausnahmen serialisierbar zu machen. Silverlight unterstützt jedoch nicht das Attribut [Serializable]. Partielle Klassen verwenden, können Sie die meisten der Ausnahmecode wiederverwenden aber [Serializable]-Attribut nur auf die .NET Framework-Variante des Codes wie in Abbildung 6 gezeigt können anwenden.
// MyException.cs
Public partial class MyException : Exception
{
   . . .
}

// Desktop only additions to this class. 
// MyException.Desktop.cs
[Serializable]
Public partial class MyException : Exception
{
    protected  MyException (SerializationInfo info, StreamingContext context) : base(info, context) { }
}
Leider partielle Klassen von Auffindbarkeit und Lesbarkeit Probleme beeinträchtigt werden. Es ist nicht sofort deaktivieren in der Datei ihre Funktionalität befindet. Eine Klasse sollte eine einzelne Verantwortung haben und entsprechend der einzelnen Verantwortung benannt werden. Wenn Sie feststellen, dass eine Klasse in eine Möglichkeit in Silverlight und die andere in WPF verfügt, ist es nicht das einzigen Verantwortung Muster folgt. Plattformspezifischer Code in Dienste mit einem beschreibenden Namen extrahieren ist normalerweise eine bessere Lösung.

Da Visual Studio nie Multi-Zielgruppenadressierung aufzunehmen entwickelt wurde, werden Sie wahrscheinlich in einige Marotten ausführen, die durch den Ansatz verursacht werden. Keines davon sind sehr schwerwiegend, aber wissen, was sind erleichtert.
Visual Studio erkennt, dass eine verknüpfte Datei in verschiedenen Projekttypen platziert werden kann. Also je nachdem, ob die verknüpfte Datei von WPF oder Silverlight öffnen, wird es der IntelliSense entsprechend anpassen. Häufig ist es möglich, dass Sie ein Sprachkonstrukt verwenden, die in nur einer der Plattformen verfügbar ist. Buildfehler begegnen Sie werden, wenn Sie die Projektmappe kompilieren, da der Code für eine der Plattformen ungültig ist. Abhängig davon, ob Sie geöffnet bestimmt die Datei von WPF oder Silverlight, ob Sie die rote Wellenlinie angezeigt werden. Aber sobald Sie die Tatsache gewöhnt anwachsen, dass eine Änderung in einem Projekt das verknüpfte Projekt unterbrechen kann, müssen Sie schnell, wo gesucht kennen.
Projektverweise sind auch interessant. Projekt-Linker hinzufügen nicht automatisch Verweise. Wir suchten in dies beim Erstellen des Tools, aber es wurden zu viele Rand Anfragen an diese zuverlässiger machen. Beispielsweise haben die Binärdateien für Silverlight andere Namen als die Binärdateien für WPF.
Schließlich können Sie fast jede Art von Datei, z. B. Ressourcendateien verknüpfen. Allerdings sollten Sie sicherstellen, dass die Eigenschaften, z. B. die Kompilierungsoptionen zwischen beiden Projekten gleich sind.

Viele Kunden gern absolut Prism. Auch wenn die Anwendung die zusammengesetzten Funktionen nicht, die Prism bietet, profitieren es weiterhin ungeheuer flexible Architektur von, die Prism fördert. Die Möglichkeit, problemlos multi-target die Anwendung ist nur eine dieser Vorteile – und es ist eine wirklich gut! Sie können die Binärdatei herunterladen und Quellcodedateien für Project Linker Microsoft Download Center. Sie können weitere Informationen PRISM online .

Erwin van der Valk Hinweis auf die Sicherheitsanfälligkeit ist ein Entwickler auf ’s Microsoft Patterns und practices-Team. Er ist außerdem ein Scuba-Diver, einen Master Kung Fu und Metal Guitarist. Erteilen Sie ihm Code – er nach rechts, hinaus und screaming eintauchen und machen viel Rauschen während es! Auschecken der er zu macht Geräusch Erwinvandervalk. NET .

Page view tracker