Having just gone through a small experimenting session to try to see how much work it would take to bring our .NET class library, or at least portions of it, into Silverlight so that we can reuse business logic between the two worlds, I'm wondering if others have experience with this sort of thing.
The things I noticed, off the top of my head:
Lots of attributes missing (Browsable(false) for instance)
Lots of interfaces missing, or present, but empty (ICloneable is hidden, ITypedList missing)
Reflection differences (everything reachable needs to be public)
Some base class differences (no Component?)
So I'm wondering, is it really feasible for me to even look at this as a possibility?
I got the initial code running, but I had to just comment out a whole lot of the base functionality, mostly around handling lists since they are based on ITypedList and some base classes. Apparently I need to change to ObservableCollection in Silverlight, so a whole of of base-code needs to be changed in order to cope.
The actual business test class I created is 99.5% identical to the one I would've made for .NET, only some minor changes that would easily be usable in .NET as well, just not as I would've made it before looking at Silverlight. In other words, it looks feasible to share business logic, provided I can make the base classes compatible.
Just so I'm clear, what I'm talking about is that I would basically have two project files, one for .NET, and one for Silverlight, but the actual C# source code would be the same, shared between the two.
So does anyone have any experience with this? Any tips or guidelines?
Will it be worth it? It certainly warrants more looking into.
It is definitely feasible.
It's done on a project here; the Silverlight project includes the C# ones, and there are some #IF statements handling some things (like log4net declarations), and other times things are just re-implemented. But in general, it's a huge win, and you should definitely attempt it (and certainly, we have, successfully).
-- Edit:
One point though, is that our OR/M (LLBLGen) didn't have inbuilt support for 'simple' objects to send down through Silverlight; but someone had written a plugin that handled it, which helped. So it may be worth considering what sort of DAL you're using, and how well it supports Silverlight.
What I've done to facilitate this is:
Frequent use of partial classes and #if !SILVERLIGHT to separate code into parts that Silverlight can handle.
Use of code generation whenever possible. For example I've been experimenting with T4 templates that generate Silverlight equivalent attributes (DisplayAttribute instead of DescriptionAttribute for example)
Whenever there's an interface/attribute that isn't implemented by Silverlight (such as IDeserializationCallback, ICloneable, INotifyPropertyChanging) I will create a dummy interface of the same name in the Silverlight application as long as I know that the fact that the implementation won't be used is not a problem.
Finally, it's worth noting that in Silverlight 4, the assembly format does allow for sharing of binaries between Silverlight and .NET as long as there are no dependencies that Silverlight does not support.
One more note about the separate base classes - it may be worthwhile to create an abstract class that derives from ObservableCollection in Silverlight and BindingList (or whatever you're using in .NET) to minimize the impact on your typed collections.
UPDATE
Today I was working on porting some .NET code to Silverlight that made heavy use of the System.Diagnostics API's like TraceSource, SourceSwitch, etc which do not exist in Silverlight. I created very minimal implementations of these in the Silverlight project and put them in the Einstein.Diagnostics namespace. In doing so I decided I needed a convention to easily identify code that was mimicking the .NET Framework vs. my own code. So I renamed the placeholder files to prefix them with an # sign. I also prefixed the class names in those files as well. The nice thing about that is that the # sign does not actually change their class names as far as the C# compiler is concerned. So #SourceSwitch still compiles to be Einstein.Diagnostics.SourceSwitch but in the code I can easily see something is up. I've also decorated these classes with a [SilverlightPlaceholder] attribute.
I do this with protobuf-net, and I use a few approaches:
conditional compilation symbols in the project file to trigger subtle code-branches (yes, it isn't perfect, but it works)
re-introduction of some things; attributes might be an example here - your code can still use re-introduced attributes, even if the framework code doesn't; as a more extreme example of this, for compact framework I had to re-introduce a good chunk of the Expression API, which was fun
just drop some things ;-p
However if you are using ITypedList (which you mention), I can see that whole approach falling apart pretty messily; component-model is complex enough already, without having to force your way through the hacks too. It really depends quite how far you've gone down this road. Maybe 4.0 / dynamic will open up some of these options again?
One possible fix to your issue is to copy the missing code from the Mono project. Back in the day, I did a small project with the Compact Framework and it was missing the entire System.XLM namespace. I just copied the entire thing from Mono into my project, compiled it and it worked great with minimal changes, iirc.
Related
I'm working with some .NET services that have the potential to process significantly large XML documents, and I need to ensure that all processing is done in a streaming / pipelining fashion. I'm already using the XmlReader and XmlWriter classes. My question is, what is the best way to programmatically provide a filter into the reader and writer (either, depending upon the flow)?
(I am not looking for XSLT. I already do a lot with XSLT, and many of the things I'm looking to do are outside the scope of XSLT - or at least, implementing within XSLT would not be ideal.)
In Java & SAX, this would best be handled through a XMLFilterImpl. I do not see that .NET provides anything similar for working with a XmlReader. I did find this blog post, "On creating custom XmlReaders/XmlWriters in .NET 2.0, Part 2", which includes the following (I've fixed the first link from a broken link from the original post):
Here is the idea - have an utility wrapper class, which wraps
XmlReader/XmlWriter and does nothing else. Then derive from this class
and override methods you are interested in. These utility wrappers are
called XmlWrapingReader and XmlWrapingWriter. They are part of
System.Xml namespace, but unfortunately they are internal ones -
Microsoft XML team has considered making them public, but in the
Whidbey release rush decided to postpone this issue. Ok, happily these
classes being pure wrappers have no logic whatsoever so anybody who
needs them can indeed create them in a 10 minutes. But to save you
that 10 minutes I post these wrappers here. I will include
XmlWrapingReader and XmlWrapingWriter into the next Mvp.Xml library
release.
These 2 classes (XmlWrappingReader and XmlWrappingWriter) from the Mvp.Xml library are currently meeting my needs nicely. (As an added-bonus, it is a free & open-source library, BSD licensed.) However, due to the stale status of this project, I do have some concerns with including these classes in a contracted, commercial development project that will be handed-off. The last release of Mvp.Xml was 4.5 years ago in July 2007. Additionally, there is this comment from a "project coordinator" in response to this project discussion:
Anyway, this is not really a supported project anymore. All devs moved
out. But it's open source, you are on your own.
I've also found SAX equivalent in .Net, but SAXDotNet doesn't seem to be in any better shape - with its last release being in 2006.
I'm well aware that a stale project doesn't necessarily mean that it is any less useable, and will be moving forward with the 2 wrapper classes from the Mvp.Xml library - at least for now.
Are there any better alternatives that I should be considering? (Again, any solution must not require the entire XML to exist in-memory at any one time - whether as a DOM, a string, or otherwise.) Are there any other libraries available (preferably something from a more active project), or maybe something within the LINQ features that would meet these requirements?
Personally I find that writing a pipeline of filters works much better with a push model than a pull model, although both are possible. With a pull model, a filter that needs to generate multiple output events in response to a single input event is quite tricky to program, though of course it can be done by keeping track of the state. So I think that looking for a SAX-like approach makes sense.
I would look again at SaxDotNet or equivalents. Be prepared to look at the source code and bend it to your needs; consider contributing back your improvements. Intrinsically the job it is doing is very simple: a loop that reads events from the (pull) input and writes events to the (push) output. In fact, it's so simple that perhaps the reason it hasn't changed since 2006 is that it doesn't need to.
The generic Func<> and Action<> delegates from later versions of .NET are very appealing, and it's been demonstrated in many places that these can easily be recreated in code targeting .NET 2.0, such as here.
From the perspective of a library targeting .NET 2.0 however, which may be consumed by applications built against any higher version of .NET, how does this stack up. Is implementing this "compatibility layer" within the library absolutely a recipe for conflict (both in terms of private and public interface), or are there ways to make this work independent of the target framework that the consuming application builds against?
If this is a non-starter, would it be better to either:
A) Define an identical set of parametrized delegates with different names? or..
B) Stick strictly with .NET 2.0 convention, and define new delegate types as I need them?
The plain truth is that Func<> and Action<> are a good idea. They make your code much easier to read and they avoid a shocking amount of messy boilerplate delegate declarations. That's why you want to use them.
So you have this really appealing programming style you want to use, it's a standard technique that is now used almost universally instead of the old way, but you can't use it because you are targeting a legacy version of the framework. What should you do?
You have three choices:
Use the programming style that was in common use before the feature
Add the feature to your own code in spirit but with non-conflicting names
Add the feature to your own code with the "real" names but in your own namespace
Using the old programming style gives up all the benefits that we have come to appreciate from the feature. That's a big sacrifice. But maybe all your co-developers are used to this style of programming.
Using the feature with non-conflicting names seems sensible enough. People will be able to read the code and benefit from the features, but no-one will be confused that they appear to be something that they're not. When you are finally ready to upgrade, you'll have to patch up the names. Luckily Ctrl+R, Ctrl+R makes doing that very easy.
Using the feature with the same names as the standard feature means your code can target an older version but appear to be using newer features. Seems like a win/win. But this could cause confusion and you have to be careful that your types aren't exposed to other unknowing assemblies, possibly causing source level compilation problems. So you have to be careful and be perfectly clear about what is happening. But it can work effectively.
You have to pick whatever approach makes sense in your situation depending on your needs. There is no one right answer for everybody, only trade-offs.
I have an application that I have designed and this app has a pretty decent core dll that contains an API that my main view's exe uses. I would like to allow other developers to access this core dll as well but I don't want them to have as much access as me since it would be a security risk. What is the standard way of exposing my core dll? Are there any particular design patterns I should be looking at?
I'm using C#
Edit: my question was a little vague so here is some clarification
My program is deployed as a windows exe which references the core.dll. I want other people to create extensions which dynamically get loaded into my program at start up by loading dlls in the /extensions directory. The 3rd party dlls will inherit/implement certain classes/interfaces in my core.dll. I only want to give 3rd parties limited access to my core but I want to give my exe additional access to the core.
I should mention that this is the first time I have written a program that imports DLLs. Perhaps this whole method of allowing users to add extensions is wrong.
How do I modify/expose my API for
other developers?
To deliberately allow other developers to work with an API you've built touches on many things, which can be broken into two areas:
Resources (documentation, samples, etc) that makes it easier for them to understand (yes - basically an SDK).
Architecting, constructing and deploying your solution so that it's easy to actually work with.
Examples include:
By packing it in a way that suits re-use.
By using naming conventions and member names that others can easily follow.
Documentation, samples.
Providing the source code (as open source) if you're happy for them to modify it.
I would like to allow other developers
to access this core dll as well but I
don't want them to have as much access
as me since it would be a security
risk.
Ok, so this gets us right into the second area - the actual solution.
The problem you have is not a trivial one - but it's also quite do-able; I'd suggest:
Looking into existing material on plugins (https://stackoverflow.com/questions/tagged/plugins+.net)
Personally, I've found using attributes and Dependency Inversion to be a great approach.
There's also stuff like the Managed Extensibility Framework which you should consider.
The big issue you face is that you're into serious architecture territory - the decisions you make now will have a profound impact on all aspects of the solution over time. So you might not be able to make an informed decision quickly. Still - you have to start somewhere :)
The "design patterns" in terms of an API are more related to things like REST.
I don't want them to have as much
access as me since it would be a
security risk
Then i would (for the sake of maintenance), layer on top of the core DLL extra logic to prevent this.
The thing is, the "clients" call the API, not the Core DLL.
"How" the API accesses the Core DLL is under your full control. Just only expose operation contracts that you wish.
Since you're using C#, I would look at Microsoft's Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries and use FxCop to in-force many of them (latest version here). This won't be all you'll likely need, but it would help put you in the right direction.
Also, take a look at the freely available distillation of Framework Design Guidelines by the same author.
Question
Is there a mechanism in the .NET Framework to hide one custom Type from another without using separate projects/assemblies? I'm not talking about access modifiers to hide members of a Type from another type - I mean to hide the Type itself.
Background
I'm working in an ASP.NET Website project and the team has decided not to use separate project assemblies for different software layers. Therefore I'm looking for a way to have, for example, a DataAccess/ folder of which I disallow its classes to access other Types in the same ASP.NET Website project. In other words I want to fake the layers and have some kind of security mechanism around each layer to prevent it from accessing another.
More Info and Details ...
Obviously there's not a way to enforce this restriction using language-specific OO keywords so I am looking for something else, for example: maybe a permission framework or code access mechanism, maybe something that uses meta data like Attributes. Even something that restricts one namespace from accessing another. I'm unsure the final form it might take.
If this were C++ I'd likely be using friend to make as solution, which doesn't translate to C# internal in this case although they're often compared.
I don't really care whether the solution actually hides Types from each other or just makes them inaccessible; however I don't want to lock down one Type from all others, another reason access modifiers are not a solution. A runtime or design time answer will suffice. Looking for something easy to implement otherwise it's not worth the effort ...
You could use NDepend to do this:
http://www.ndepend.com/
NDepend could allow you to enforce "layering" rules by specifying that certain namespaces should not reference each other. You then plug NDepend and the ruleset into your automated build, and it will fail the build (with a full report) if there are any misdemeanours.
In this way you can enforce logical software layering concepts within an assembly without having to use project structures to do it physically.
Update
I answered the question late last night, and rather literally i.e. how you can directly solve the question. Although a tool can be used to solve the issue, developing in one project across the whole team is more than likely going to be a pretty miserable experience as the project grows:
Unless people are incredibly disciplined, the build will keep breaking on layering violations.
There will be source control merge thrashing on the VS project file - not pleasant.
Your unit of re-use is very large and undefined if you want to share assemblies with other applications\projects you are developing. This could lead to very undesired coupling.
Although I do not advocate having lots of tiny assemblies, a sensible number defined around core concepts is very workable and desirable e.g. "UI", "data access", "business logic", "common library" and "shared types".
Nothing out of the box; there may be some 3rd-party tools that you can use to kludge some rules together, based perhaps on namespaces etc. Something like a custom fx cop rule...
I have a goal to build an application with UI that would run on both Windows Mobile and "normal" desktop Windows. The priority is for it to "look good" under Windows Mobile, and for desktop Windows it is OK if it distorted. Before I invest days trying, I would like to hear if that is possible to begin with. There are several parts to this question:
Is .NET Compact Framework a subset of "normal" (please, edit) .NET Framework? If not, does MSDN have any information anywhere on classes that are in .NET Compact Framework, but not in "normal" (again, please, edit) framework?
Is behavior of shared classes same in both frameworks?
Is it possible to have a single Visual Studio 2005 solution / project for both platforms? If yes, how do to set it up?
Any other comments and advice? Any relevant links?
The CF contains a subset of the full framework (FFx), but it is not a pure subset. There are actually several things available in the CF that aren't in the FFx, which makes it a bit more difficult. CF apps also, except in the most rudimentary cases, use P/Invoke. Those calls are never the same from the desktop to the device, so they are not directly portable (though with a little abstraction you can have a platform-agnostic interface).
For the most part, behavior is the same. I've seen some cases where it's not, and I recall some event ordering not always being identical though, so trust but verify.
It's possible through very careful massaging of the configurations, but I certainly don't recommend it. It's difficult to maintain and very fragile. Instead have two project files, one for CF and one for FFx. You're likely to have code file differences anyway. Add the code files as links to each project so they both use the same physical source file. I'd recommend using some form of CI to help ensure they both build at all times.
Take a look at Dan Moth's MSDN article and blog entries on sharing code assets.
P.S. I found the poster online - it'll show you all the classes that are CF. I ordered it fro Microsoft because Kinkos wanted $65 to print it out in color for me! Microsoft sent me a couple of copies free - all I had to do was ask:
http://www.microsoft.com/downloads/details.aspx?familyid=7B645F3A-6D22-4548-A0D8-C2A27E1917F8&displaylang=en
I have it hanging in my cubicle and it's a godsend when trying to remember which namespaces classes can be found in.
Nice multi-part question:
Differences between the Full Framework and the Compact Framework
The article above has links to relevant documentation about how class behavior differs (it definitely DOES differ in some situations)
Very simple! Create a single solution with a set of base functionality in a Class Library, then create two client projects (one for your desktop app and one for the windows mobile app). Finally, add references to the class library to both client projects.
Depending on the breadth of the project you are working on, you may want to check out the Model View Controller pattern. It may be a bit much for your project, but if you want to share UI behavior between projects, it can be a life saver.
Hope that helps!
CF, in general contains a subset of the classes from the regular framework - but you can't directly execute code from one on t'other. Additionally, rather than just being a subset, there are probably a few things in compact that aren't in the regular version, such as the GUI things specific for mobile devices (soft keys, etc) - assuming you are writing a winform exe, and not a web page (which might be the simplest way to get compatibility).
With some effort, it it possible to share logic code, in particular utility dlls - but they need different csproj files (since they have completely different compile-time "targets"). To reduce maintenance, you can often cheat by hacking the csproj to use wildcards, like from here:
<ItemGroup>
<Compile Include="..\protobuf-net\**\*.cs" />
</ItemGroup>
For UI, things get a lot tricker. In general the expectation would be to have shared business logic and separate UI for different target devices.
1). There is a Compact Framework so yes; And it is a subset of the full .NET framework. I've got a poster on my wall at the office that denotes a whole bunch of classes that work in CF... I don't recall off the top of my head if there are any that are purely CF, but I suppose there must be some. There are a couple of good books on the subject - one by Paul Yao that I have and another by Andy Wigley - both are available on Amazon.
2). As far as I'm aware, the classes that are CF and full framework work the same but need to be compiled for different targets.
3). I would hazard a guess that providing you only use classes that are common to both, that you could use the same solution, I don't know the extent you would have to go to make it compile for the compact device and the full version though, nor can I say with complete certainty that it can be done. I'd hazard a guess that the process isn't simple.
4). Go to your local book store and have a flick through those two books I mentioned. Like I said, I have the one by Paul Yao and it seems to cover most of what I could imagine needing on a compact device.