2
votes

I'm creating a Portable Class Library and Targeting .Net 4.5, Windows 8, Windows Phone 8.1 and Windows Phone Silverlight 8.

Can I limit a class or method to a specific target? Like a method can only be called from a .Net 4.5 project, and not from a Windows Phone 8.1 project.

Is this possible?

2
That rather defeats the point of a PCL project. If you are going to force yourself to create separate builds then just don't bother with it.Hans Passant

2 Answers

2
votes

This is feasible using Dependency Injection.

For instance, you may use contextual binding with Ninject to inject the appropriate type implementation so that this method call shall do nothing whilst another implementation shall do what is intended.

public abstract class MyBaseClass {
    public abstract void MyMethod() { }
}

public class MyDerivedDotNet45Class : MyBaseclass() {
    public override void MyMethod() { // Does something... }
}

public class MyDerivedWindowsPhoneClass : MyBaseClass() {
    public override void MyMethod() { // Does nothing... }
}

public class MyWorkingProcessClass {
    public MyWorkingProcessClass(MyBaseClass baseClass) {
        dependency = baseClass;
    }

    public void MethodThatShallDoSomethingOnlyWhenDotNet45() {
        dependency.MyMethod();
    }

    private readonly MyBaseClass dependency;
}

So depending on which class you inject, your program shall either do something or nothing.

Under .Net 4.5

var workingClass = new MyWorkingProcessClass(new MyDerivedDotNet45Class());
wokringClass.MethodThatShallDoSomethingOnlyWhenDotNet45();

This shall do something as stated in the derived class.

Under Windows Phone

var workingClass = new MyWorkingProcessClass(new MyDerivedWindowsPhoneClass());
workingClass.MethodThatShallDoSomethingOnlyWhenDotNet45();

This shall do nothing as stated in the derived class.

Using Ninject

This answer provides with a good example of using Contextual Binding.

This is in the Composition Root that you shall build your object composition so that it knows what to inject where and when.

1
votes

Yes, by using directives that specify those platforms. Now I'm not entirely sure if there is a .NET 4.5 directive automatically available but as far as I know there are the

#SILVERLIGHT, #WINDOWS_PHONE, #WP8 and #NETFX_CORE directives available.

You can use them like this:

#if WINDOWS_PHONE
   int x = 1;
# else
   int x = 2;
#endif

In your situation you would place them around the method so the method would only get compiled if the right projects are targetted.

I believe #NETFX_CORE only indicates it is Windows 8 and not .NET. There might be .NET specific directives but they aren't set automatically for the projects you're referring to (probably because those use WinRT, not .NET per sé).

However this answer indicates that you could set it with a custom directive:

<DefineConstants Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">
    RUNNING_ON_4
</DefineConstants>