xamarin
परियोजनाओं के बीच कोड साझा करना
खोज…
ब्रिज पैटर्न
ब्रिज पैटर्न नियंत्रण डिजाइन पैटर्न के सबसे बुनियादी उलटा में से एक है। ज़मारिन के लिए, इस पैटर्न का उपयोग प्लेटफ़ॉर्म-डिपेंडेंट कोड से प्लेटफ़ॉर्म-इंडिपेंडेंट संदर्भ के संदर्भ में किया जाता है। उदाहरण के लिए: पोर्टेबल क्लास लाइब्रेरी या ज़मारिन फॉर्म्स से एंड्रॉइड के एलर्टडायलॉग का उपयोग करना। उन संदर्भों में से कोई भी नहीं जानता है कि एक एलर्टडायलॉग ऑब्जेक्ट क्या है, इसलिए आपको उन्हें उपयोग करने के लिए एक बॉक्स में लपेटना होगा।
// Define a common interface for the behavior you want in your common project (Forms/Other PCL)
public interface IPlatformReporter
{
string GetPlatform();
}
// In Android/iOS/Win implement the interface on a class
public class DroidReporter : IPlatformReporter
{
public string GetPlatform()
{
return "Android";
}
}
public class IosReporter : IPlatformReporter
{
public string GetPlatform()
{
return "iOS";
}
}
// In your common project (Forms/Other PCL), create a common class to wrap the native implementations
public class PlatformReporter : IPlatformReporter
{
// A function to get your native implemenation
public static func<IPlatformReporter> GetReporter;
// Your native implementation
private IPlatformReporter _reporter;
// Constructor accepts native class and stores it
public PlatformReporter(IPlatformReporter reporter)
{
_reporter = GetReporter();
}
// Implement interface behavior by deferring to native class
public string GetPlatform()
{
return _reporter.GetPlatform();
}
}
// In your native code (probably MainActivity/AppDelegate), you just supply a function that returns your native implementation
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
PlatformReporter.GetReporter = () => { return new DroidReporter(); };
}
}
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.RootViewController = new UIViewController();
window.MakeKeyAndVisible();
PlatformReporter.GetReporter = () => { return new IosReporter(); };
return true;
}
}
// When you want to use your native implementation in your common code, just do as follows:
public void SomeFuncWhoCares()
{
// Some code here...
var reporter = new PlatformReporter();
string platform = reporter.GetPlatform();
// Some more code here...
}
सेवा लोकेटर पैटर्न
सेवा लोकेटर डिजाइन पैटर्न बहुत निर्भरता इंजेक्शन है। ब्रिज पैटर्न की तरह, इस पैटर्न का उपयोग प्लेटफ़ॉर्म-डिपेंडेंट कोड से प्लेटफ़ॉर्म-इंडिपेंडेंट संदर्भ को संदर्भित करने के लिए किया जा सकता है। सबसे दिलचस्प बात यह है कि यह पैटर्न सिंगलटन पैटर्न पर निर्भर करता है - जो कुछ आप सेवा लोकेटर में डालते हैं वह डिफैक्टो सिंगलटन होगा।
// Define a service locator class in your common project
public class ServiceLocator {
// A dictionary to map common interfaces to native implementations
private Dictionary<object, object> _services;
// A static instance of our locator (this guy is a singleton)
private static ServiceLocator _instance;
// A private constructor to enforce the singleton
private ServiceLocator() {
_services = new Dictionary<object, object>();
}
// A Singleton access method
public static ServiceLocator GetInstance() {
if(_instance == null) {
_instance = new ServiceLocator();
}
return _instance;
}
// A method for native projects to register their native implementations against the common interfaces
public static void Register(object type, object implementation) {
_services?.Add(type, implementation);
}
// A method to get the implementation for a given interface
public static T Resolve<T>() {
try {
return (T) _services[typeof(T)];
} catch {
throw new ApplicationException($"Failed to resolve type: {typeof(T).FullName}");
}
}
//For each native implementation, you must create an interface, and the native classes implementing that interface
public interface IA {
int DoAThing();
}
public interface IB {
bool IsMagnificent();
}
public class IosA : IA {
public int DoAThing() {
return 5;
}
}
public class DroidA : IA {
public int DoAThing() {
return 42;
}
}
// You get the idea...
// Then in your native initialization, you have to register your classes to their interfaces like so:
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
var locator = ServiceLocator.GetInstance();
locator.Register(typeof(IA), new DroidA());
locator.Register(typeof(IB), new DroidB());
}
}
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.RootViewController = new UIViewController();
window.MakeKeyAndVisible();
var locator = ServiceLocator.GetInstance();
locator.Register(typeof(IA), new IosA());
locator.Register(typeof(IB), new IosB());
return true;
}
}
// Finally, to use your native implementations from non-native code, do as follows:
public void SomeMethodUsingNativeCodeFromNonNativeContext() {
// Some boring code here
// Grabbing our native implementations for the current platform
var locator = ServiceLocator.GetInstance();
IA myIA = locator.Resolve<IA>();
IB myIB = locator.Resolve<IB>();
// Method goes on to use our fancy native classes
}