.net conditional compilation according to referrer assembly - silverlight

I have a WCF service interface in a portable class library referenced by both silverlight and service implementer. It is like this:
#if SILVERLIGHT
[ServiceContract]
public interface IService
{
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginTest(AsyncCallback cb, object state);
void EndTest(IAsyncResult ar);
}
#else
[ServiceContract]
public interface IService
{
[OperationContract]
void Test();
}
#endif
now I referenced it from SL and got a compilation error which shows that the contract is sync version and not supported by SL. I think the reason is that there is no SILVERLIGHT defined in the portable library. But I don't want to define one because it is referenced by another non-silverlight libraries. Is there any way to let compiler automatic select right version to compile according to the category of the referrer project without modifying the portable library?

No. You would need to have two separate assemblies with the different APIs.
You might be able to keep a single portable library if you just use an async method returning Task instead of the Begin/End pattern. You can get async support on Silverlight with the Microsoft.Bcl.Async package, but I'm not sure if you can use that for WCF on Silverlight or not.

Related

Using Shiny with UNO Platform

Looking for a way to use shinyorg/shiny nuget packages in cross-platform projects built on the UNO platform.
Facing some challenges beyond my (limited) skills for iOS development, I'm specifically looking for how to integrate Shiny.Core into the solution iOS project.
More precisely, I'm looking for where to put this initialization override:
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
Since when I try adding this in the Main.cs (Application class) of the iOS project, I can't find where to start...
The Main.cs class from the iOS project contains a static Main method (which is the main entry point of the app) in which a call to UIApplication.Main(args, null, typeof(App)); is made.
UIApplication being in fact UIKit.UIApplication
Following this guide https://github.com/shinyorg/shiny/tree/master/src/Shiny.Core where it's said:
* Add the following as the first line in your AppDelegate.cs - FinishedLaunching method
using Shiny;
this.ShinyFinishedLaunching(new YourStartup());
** IOS JOBS **
If you plan to use jobs in iOS, please do the following:
1. Add this to your AppDelegate.cs
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
On iOS, the AppDelegate is actually the App class in your app, created from the default Uno Platform templates.
Windows.UI.Xaml.Application inherits from UIApplicationDelegate and provides a way declare this:
#if __IOS__
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
=> this.ShinyPerformFetch(completionHandler);
#endif
in order for the code for the other platforms to ignore this iOS-specific code

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.

System.TypeLoadException was unhandled / Inheritance security rules violated while overriding member

Can you create a .NET 4 version of your app for testing was the bosses' innocent question - sure!
But after I changed our 27 projects in our Winforms application to .NET 4, and recompiled, when launching the app, I get
System.TypeLoadException was unhandled
Message=Inheritance security rules violated while overriding member:
'MyCustomORM.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'.
Security accessibility of the overriding method must match the security accessibility of the method being overriden.
Hmmm.....
MyCustomORM does indeed implement the ISerializable interface and thus has this method
[Serializable]
public abstract class MyCustomORM: IMyCustomORM, ISerializable, ICloneable, ISecurable
{
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// do stuff here.......
}
}
and I also have two classes that derive from Exception that override the GetObjectData method.
But what could be wrong here?? Googling around I found some additional attributes to stick onto my method and namespace - so I did:
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
namespace MyApplication.ORM
{
[Serializable]
public abstract class MyCustomORM: IMyCustomORM, ISerializable, ICloneable, ISecurable
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// do stuff here.......
}
}
}
but that doesn't change anything.....
The exception happens even before my first line of code in my static Main() method is reached....
I've combed through the project and removed any references to old .NET 1.1 libraries (yes, the app is that old.....) and replaced them with their .NET 4 counterparts (mostly log4net). Still no luck....
Any ideas??
Is the assembly in which the MyCustomORM class resides marked with SecurityTransparentAttribute? If so, the problem stems from changes in the security transparency model between .NET 3.5 and .NET 4.0. For your testing scenario, you may wish to simply opt into using the older transparency mechanism. To do so, add the following assembly-level attribute:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
For more information on the differences between the Level1 and Level2 transparency models, see http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx.
I know this is pretty old, but I ran into this issue with one of my assemblies recently. It only occurred on some machines and was very difficult to determine what was causing it. I didn't just want to put security rule adjustments in, so after much searching I ran across the SecAnnotate tool that is included with Visual Studio.
Using SecAnnotate to Identify Transparency Violations
Using the tool I was able to determine that one of my assemblies was referencing an older version of a dll which contained some security attributes which were causing the problem. Updating the reference fixed the issue.
The SecAnnotate tool seems like a great way to identify any violations that you may have accidentally overlooked or didn't know about.
Hope this helps someone.

Silverlight client, datacontract, and private readonly members

I have a Silverlight client and a WCF service that I want to have share a class:
[DataContract]
public class DatesAreFun
{
[DataMember]
private readonly DateTime _date;
[DataMember]
private readonly bool _isFun;
public DateTime DateTime { get { return _date; } }
public bool IsFun { get { return _isFun; } }
public DatesAreFun(DateTime date, bool isFun)
{
_date = date;
_isFun = fun;
}
}
The WCF side seems to send the appropriate data across the wire just fine, but the Silverlight side doesn't like it one bit. It is treating the WCF service DatesAreFun class as a different class than my DatesAreFun class.
Any suggestions on how best to remedy this? Thanks!
This is a common issue and has been covered here more than a few times.
When you add your service reference, make sure you click the Advanced button, then ensure you have ticked the Reuse types in referenced assemblies checkbox, and selected the Reuse types in all referenced assemblies option.
You also have to create a new class library assembly that targets the Silverlight runtime. This is because the class library referenced by the WCF services will target the full (or maybe the client profile) version of the .Net framework, which a Silverlight assembly cannot do (in fact a Silverlight assembly can only reference other Silverlight targeted assemblies). In your new class library you can reference the same physical files that the full version of the class library is using, this is detailed more here (i had the same question once upon a time...). You could also pick your way through this bunch of search results for related questions.
Depending on how you do things you may find you also have to trawl through the Reference.cs file of the Service Reference, and change the namespaces of the named data entities. (This file will get regenerated if you update or reconfigure the service reference).

Silverlight 4 and COM Interop

I've created a ComVisible-class:
[Guid("73a3f91f-baa9-46ab-94b8-e526c22054a4"), ComVisible(true)]
public interface ITest
{
void Foo();
}
[Guid("99f72d92-b302-4fde-89bb-2dac899f5a48"), ComVisible(true)]
public class Class1 : ITest
{
public void Foo() { }
}
and registered it via
regasm ComClassTest.dll /tlb:ComClassTest.tlb
into the registry.
When I try to call it in my Silverlight 4 out-of-browser, elevated trust application like this:
var foo = AutomationFactory.CreateObject("ComClassTest.Class1");
I get an exception "{System.Exception: Failed to create an object instance for the specified ProgID."
However, I am able to call AutomationFactory.CreateObject("Word.Application") without an Exception and to call Activator.CreateInstance(Type.GetTypeFromProgID("ComClassTest.Class1")) in a normal C#-console application if I copy the ComClassTest.dll into the bin-directory.
What have I forgotton?
First thing to do is test that you can create the object from somewhere else such as VBScript. Create a .vbs file with the content:-
o = CreateObject("ComClassTest.Class1")
If that doesn't generate an error then there is something specifically that SL OOB is upset with otherwise your problem isn't really related to Silverlight at all.
Consider making the following changes to your COM code.
Its often easier to specify ComVisible(true) at the assembly level. You can do that from the application tab of the project properties on the Assembly Information dialog. You can also get Visual Studio to register the assembly with COM and build time using the option found on the build tab of the project properties.
Its a good idea to be specific about the ComInterfaceType you want to expose.
Things get really messy if you expose the class interface directly generally you only want the interface you have defined to be used and that this be the default interface for the class. In addition it probably better to stick to COM naming conventions for the default interface of a class.
Finally (and possibly crucially in your case) its a good idea to be explicit about the ProgId to use for the class.
Applying the above and we get:-
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("73a3f91f-baa9-46ab-94b8-e526c22054a4")]
public interface _Class1
{
void Foo();
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("99f72d92-b302-4fde-89bb-2dac899f5a48")]
[ProgId("ComClassTest.Class1")]
public class Class1 : _Class1
{
public void Foo() { }
}

Resources