You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by mm...@apache.org on 2021/12/08 23:16:04 UTC

[geode-native] branch GEODE-9712-genericize-netcore created (now 2503eed)

This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a change to branch GEODE-9712-genericize-netcore
in repository https://gitbox.apache.org/repos/asf/geode-native.git.


      at 2503eed  Genericize netcore-lib

This branch includes the following new commits:

     new a5fc920  Modify tests for generics (wip)
     new 2503eed  Genericize netcore-lib

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[geode-native] 01/02: Modify tests for generics (wip)

Posted by mm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a commit to branch GEODE-9712-genericize-netcore
in repository https://gitbox.apache.org/repos/asf/geode-native.git

commit a5fc92096f969326da2edb10c2d81dce615d571b
Author: Mike Martell <mm...@pivotal.io>
AuthorDate: Wed Dec 8 15:14:07 2021 -0800

    Modify tests for generics (wip)
---
 netcore/netcore-integration-test/CacheTest.cs      |  2 +-
 .../netcore-integration-test/RegionFactoryTest.cs  | 34 ++++++++++++----------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/netcore/netcore-integration-test/CacheTest.cs b/netcore/netcore-integration-test/CacheTest.cs
index f35d181..ececc4f 100644
--- a/netcore/netcore-integration-test/CacheTest.cs
+++ b/netcore/netcore-integration-test/CacheTest.cs
@@ -80,7 +80,7 @@ namespace Apache.Geode.Client.IntegrationTests {
       cacheFactory.PdxIgnoreUnreadFields = true;
       using var cache = cacheFactory.CreateCache();
       Assert.NotNull(cache);
-      using var regionFactory = cache.CreateRegionFactory(
+      var regionFactory = cache.CreateRegionFactory<string>(
           RegionShortcut.Proxy);  // lgtm[cs / useless - assignment - to - local]
       Assert.NotNull(regionFactory);
     }
diff --git a/netcore/netcore-integration-test/RegionFactoryTest.cs b/netcore/netcore-integration-test/RegionFactoryTest.cs
index edac8ad..a995547 100644
--- a/netcore/netcore-integration-test/RegionFactoryTest.cs
+++ b/netcore/netcore-integration-test/RegionFactoryTest.cs
@@ -57,38 +57,41 @@ namespace Apache.Geode.Client.IntegrationTests {
           poolFactory.CreatePool("myPool");  // lgtm[cs / useless - assignment - to - local]
     }
 
-    private void doPutsAndGets(Region region) {
+    private void doPutsAndGets(IRegion<object, object> region) {
       var fullname1 = "Robert Timmons";
       var fullname2 = "Sylvia Charles";
+      var car = new Dictionary<int, string>() { { 1, "Ford" }, { 2, "Chevy" } };
 
-      region.PutString(Username1, fullname1);
-      region.PutString(Username2, fullname2);
+      region.Put(Username1, fullname1);
+      region.Put(777, fullname2);
+      region.Put(888, car);
 
-      var user1 = region.GetString(Username1);
-      var user2 = region.GetString(Username2);
+      var user1 = region.Get(Username1);
+      var user2 = region.Get(777);
+      var car1 = region.Get(888);
 
       Assert.Equal(user1, fullname1);
       Assert.Equal(user2, fullname2);
     }
 
-    private void DoRemoves(Region region) {
-      region.Remove(Username1);
-      region.Remove(Username2);
+    private void DoRemoves(IRegion<string, string> region) {
+      //region.Remove(Username1);
+      //region.Remove(Username2);
 
-      var hasUser1 = region.ContainsValueForKey(Username1);
-      var hasUser2 = region.ContainsValueForKey(Username2);
+      //var hasUser1 = region.ContainsValueForKey(Username1);
+      //var hasUser2 = region.ContainsValueForKey(Username2);
 
-      Assert.False(hasUser1);
-      Assert.False(hasUser2);
+      //Assert.False(hasUser1);
+      //Assert.False(hasUser2);
     }
 
     private void CreateRegionAndDoWork(IGeodeCache cache, string regionName,
                                        RegionShortcut regionType) {
-      using var regionFactory = cache.CreateRegionFactory(regionType);
-      using var region = regionFactory.CreateRegion(regionName);
+      var regionFactory = cache.CreateRegionFactory<string>(regionType);
+      var region = regionFactory.Create<object, object>(regionName);
 
       doPutsAndGets(region);
-      DoRemoves(region);
+      //DoRemoves(region);
     }
 
     [Fact]
@@ -102,6 +105,7 @@ namespace Apache.Geode.Client.IntegrationTests {
                     .CreatePool("myPool");
 
         CreateRegionAndDoWork(cache, "exampleRegion", RegionShortcut.Proxy);
+
     }
 
     [Fact]

[geode-native] 02/02: Genericize netcore-lib

Posted by mm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a commit to branch GEODE-9712-genericize-netcore
in repository https://gitbox.apache.org/repos/asf/geode-native.git

commit 2503eedd75c8ee9320cf48a4d01af6b4d5d65815
Author: Mike Martell <mm...@pivotal.io>
AuthorDate: Wed Dec 8 15:15:39 2021 -0800

    Genericize netcore-lib
---
 netcore/netcore-lib/Cache.cs                       | 113 ++++++++++----------
 netcore/netcore-lib/{Cache.cs => CacheInterop.cs}  |   8 +-
 .../netcore-lib/{IRegionService.cs => IRegion.cs}  |  12 ++-
 netcore/netcore-lib/IRegionService.cs              |   8 +-
 netcore/netcore-lib/PoolManager.cs                 |   7 ++
 netcore/netcore-lib/Region.cs                      | 117 +++++++--------------
 netcore/netcore-lib/RegionFactory.cs               |  44 +++++---
 .../{RegionFactory.cs => RegionFactoryInterop.cs}  |  10 +-
 .../netcore-lib/{Region.cs => RegionInterop.cs}    |  69 +++++++++---
 9 files changed, 206 insertions(+), 182 deletions(-)

diff --git a/netcore/netcore-lib/Cache.cs b/netcore/netcore-lib/Cache.cs
index 200e740..064b963 100644
--- a/netcore/netcore-lib/Cache.cs
+++ b/netcore/netcore-lib/Cache.cs
@@ -20,59 +20,29 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class Cache : GeodeNativeObject, IGeodeCache {
+  public class Cache : IGeodeCache {
+    private IntPtr _cacheFactory;
+    private CacheInterop _cacheInterop;
     private static string _name = String.Empty;
     private PoolManager _poolManager = null;
     private PoolFactory _poolFactory = null;
     private IAuthInitialize _authInitialize;
     private GetCredentialsDelegateInternal _getCredentialsDelegate;
     private CloseDelegateInternal _closeDelegate;
+    private bool disposedValue;
 
     internal delegate void GetCredentialsDelegateInternal(IntPtr cache);
 
     internal delegate void CloseDelegateInternal();
 
-    [DllImport(Constants.libPath, CallingConvention = CallingConvention.Cdecl)]
-    private static extern void apache_geode_CacheFactory_SetAuthInitialize(
-        IntPtr factory, GetCredentialsDelegateInternal getCredentials,
-        CloseDelegateInternal close);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_CacheFactory_CreateCache(IntPtr factory);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_GetPdxIgnoreUnreadFields(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_GetPdxReadSerialized(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Cache_GetName(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Cache_Close(IntPtr cache, bool keepalive);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_IsClosed(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_AuthInitialize_AddProperty(IntPtr properties,
-                                                                       IntPtr key,
-                                                                       IntPtr value);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_DestroyCache(IntPtr cache);
-
     internal Cache(IntPtr cacheFactory, IAuthInitialize authInitialize) {
       _authInitialize = authInitialize;
+      _cacheFactory = cacheFactory;
+      _cacheInterop = new CacheInterop(cacheFactory, authInitialize);
       if (_authInitialize != null) {
         _getCredentialsDelegate = new GetCredentialsDelegateInternal(AuthGetCredentials);
         _closeDelegate = new CloseDelegateInternal(AuthClose);
-
-        apache_geode_CacheFactory_SetAuthInitialize(cacheFactory, _getCredentialsDelegate,
-                                                    _closeDelegate);
       }
-      _containedObject = apache_geode_CacheFactory_CreateCache(cacheFactory);
     }
 
     internal void AuthGetCredentials(IntPtr properties) {
@@ -87,7 +57,7 @@ namespace Apache.Geode.Client {
         Console.WriteLine("Found credential: (k, v) = ({0}, {1})", entry.Key, entry.Value);
         var keyPtr = Marshal.StringToCoTaskMemUTF8(entry.Key);
         var valuePtr = Marshal.StringToCoTaskMemUTF8(entry.Value);
-        apache_geode_AuthInitialize_AddProperty(properties, keyPtr, valuePtr);
+        //apache_geode_AuthInitialize_AddProperty(properties, keyPtr, valuePtr);
         Marshal.FreeCoTaskMem(keyPtr);
         Marshal.FreeCoTaskMem(valuePtr);
       }
@@ -98,25 +68,33 @@ namespace Apache.Geode.Client {
     }
 
     public void Close() {
-      apache_geode_Cache_Close(_containedObject, false);
+      _cacheInterop.Close();
     }
 
     public void Close(bool keepalive) {
-      apache_geode_Cache_Close(_containedObject, keepalive);
+      _cacheInterop.Close(keepalive);
+    }
+
+    public bool Closed
+    {
+      get
+      {
+        return _cacheInterop.Closed;
+      }
     }
 
     public bool GetPdxIgnoreUnreadFields() {
-      return apache_geode_Cache_GetPdxIgnoreUnreadFields(_containedObject);
+      return _cacheInterop.GetPdxIgnoreUnreadFields();
     }
 
     public bool GetPdxReadSerialized() {
-      return apache_geode_Cache_GetPdxReadSerialized(_containedObject);
+      return _cacheInterop.GetPdxReadSerialized();
     }
 
     public string Name {
       get {
         if (_name == String.Empty) {
-          _name = Marshal.PtrToStringUTF8(apache_geode_Cache_GetName(_containedObject));
+          _name = _cacheInterop.Name;
         }
 
         return _name;
@@ -126,7 +104,8 @@ namespace Apache.Geode.Client {
     public PoolManager PoolManager {
       get {
         if (_poolManager == null) {
-          _poolManager = new PoolManager(_containedObject);
+          //_poolManager = new PoolManager(_cacheInterop);
+          _poolManager = _cacheInterop.PoolManager;
         }
 
         return _poolManager;
@@ -137,30 +116,44 @@ namespace Apache.Geode.Client {
       get {
         if (_poolFactory == null) {
           _poolFactory = PoolManager.CreatePoolFactory();
+          //_poolFactory = _cacheInterop.PoolManager.CreatePoolFactory();
         }
 
         return _poolFactory;
       }
     }
 
-    public RegionFactory CreateRegionFactory(RegionShortcut regionType) {
-      return new RegionFactory(_containedObject, regionType);
+    public RegionFactory<TValue> CreateRegionFactory<TValue>(RegionShortcut regionType) {
+      return new RegionFactory<TValue>(_cacheInterop, regionType);
     }
 
-    public bool Closed => apache_geode_Cache_IsClosed(_containedObject);
-
-    protected override void DestroyContainedObject() {
-      // It turns out, C# "wrapper" objects need to get rid of
-      // *all* contained objects, due to vagaries of Geode
-      // Native object graph, in order to ensure a leak-free
-      // shutdown.  We get rid of our non-cache objects first
-      // here, in case it makes a difference.
-      _poolManager?.Dispose();
-      _poolManager = null;
-      _poolFactory?.Dispose();
-      _poolFactory = null;
-      apache_geode_DestroyCache(_containedObject);
-      _containedObject = IntPtr.Zero;
+    protected virtual void Dispose(bool disposing)
+    {
+      if (!disposedValue)
+      {
+        if (disposing)
+        {
+          // TODO: dispose managed state (managed objects)
+        }
+
+        // TODO: free unmanaged resources (unmanaged objects) and override finalizer
+        // TODO: set large fields to null
+        disposedValue = true;
+      }
+    }
+
+    // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
+    // ~Cache()
+    // {
+    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+    //     Dispose(disposing: false);
+    // }
+
+    public void Dispose()
+    {
+      // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+      Dispose(disposing: true);
+      GC.SuppressFinalize(this);
     }
   }
-}
+  }
diff --git a/netcore/netcore-lib/Cache.cs b/netcore/netcore-lib/CacheInterop.cs
similarity index 95%
copy from netcore/netcore-lib/Cache.cs
copy to netcore/netcore-lib/CacheInterop.cs
index 200e740..f8fe5a1 100644
--- a/netcore/netcore-lib/Cache.cs
+++ b/netcore/netcore-lib/CacheInterop.cs
@@ -20,7 +20,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class Cache : GeodeNativeObject, IGeodeCache {
+  public class CacheInterop : GeodeNativeObject {
     private static string _name = String.Empty;
     private PoolManager _poolManager = null;
     private PoolFactory _poolFactory = null;
@@ -63,7 +63,7 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern void apache_geode_DestroyCache(IntPtr cache);
 
-    internal Cache(IntPtr cacheFactory, IAuthInitialize authInitialize) {
+    internal CacheInterop(IntPtr cacheFactory, IAuthInitialize authInitialize) {
       _authInitialize = authInitialize;
       if (_authInitialize != null) {
         _getCredentialsDelegate = new GetCredentialsDelegateInternal(AuthGetCredentials);
@@ -143,8 +143,8 @@ namespace Apache.Geode.Client {
       }
     }
 
-    public RegionFactory CreateRegionFactory(RegionShortcut regionType) {
-      return new RegionFactory(_containedObject, regionType);
+    public RegionFactoryInterop CreateRegionFactory<TValue>(RegionShortcut regionType) {
+      return new RegionFactoryInterop(_containedObject, regionType);
     }
 
     public bool Closed => apache_geode_Cache_IsClosed(_containedObject);
diff --git a/netcore/netcore-lib/IRegionService.cs b/netcore/netcore-lib/IRegion.cs
similarity index 65%
copy from netcore/netcore-lib/IRegionService.cs
copy to netcore/netcore-lib/IRegion.cs
index d635d71..33b0186 100644
--- a/netcore/netcore-lib/IRegionService.cs
+++ b/netcore/netcore-lib/IRegion.cs
@@ -17,7 +17,15 @@
 using System;
 
 namespace Apache.Geode.Client {
-  public interface IRegionService {
-    RegionFactory CreateRegionFactory(RegionShortcut regionType);
+  //public interface IRegion<TKey, TValue> {
+  //      void Put(TKey key, TValue value); 
+  //      TValue Get(TKey key);
+  //}
+  public interface IRegion<TKey, TValue>
+  {
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    void Put(TKey key, TValue value);
+    TValue Get(TKey key);
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
   }
 }
diff --git a/netcore/netcore-lib/IRegionService.cs b/netcore/netcore-lib/IRegionService.cs
index d635d71..87063a7 100644
--- a/netcore/netcore-lib/IRegionService.cs
+++ b/netcore/netcore-lib/IRegionService.cs
@@ -17,7 +17,9 @@
 using System;
 
 namespace Apache.Geode.Client {
-  public interface IRegionService {
-    RegionFactory CreateRegionFactory(RegionShortcut regionType);
-  }
+
+public interface IRegionService {
+  RegionFactory<TValue> CreateRegionFactory<TValue>(RegionShortcut regionType);
 }
+
+}
\ No newline at end of file
diff --git a/netcore/netcore-lib/PoolManager.cs b/netcore/netcore-lib/PoolManager.cs
index 5a06436..b7f1d73 100644
--- a/netcore/netcore-lib/PoolManager.cs
+++ b/netcore/netcore-lib/PoolManager.cs
@@ -19,6 +19,8 @@ using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
   public class PoolManager : GeodeNativeObject {
+    private CacheInterop cacheInterop;
+
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_Cache_GetPoolManager(IntPtr cache);
 
@@ -29,6 +31,11 @@ namespace Apache.Geode.Client {
       _containedObject = apache_geode_Cache_GetPoolManager(cache);
     }
 
+    public PoolManager(CacheInterop cacheInterop)
+    {
+      this.cacheInterop = cacheInterop;
+    }
+
     public PoolFactory CreatePoolFactory() {
       return new PoolFactory(_containedObject);
     }
diff --git a/netcore/netcore-lib/Region.cs b/netcore/netcore-lib/Region.cs
index 68d49a5..17111ee 100644
--- a/netcore/netcore-lib/Region.cs
+++ b/netcore/netcore-lib/Region.cs
@@ -15,100 +15,59 @@
  * limitations under the License.
  */
 using System;
-using System.Runtime.InteropServices;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 
 namespace Apache.Geode.Client {
-  public class Region : GeodeNativeObject {
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_RegionFactory_CreateRegion(IntPtr cache,
-                                                                         IntPtr regionName);
+  public class Region<TKey, TValue> : IRegion<TKey, TValue> {
+  //public class Region<TValue> : IRegion<TValue> {
+    RegionInterop _regionInterop;
 
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_PutString(IntPtr region, IntPtr key,
-                                                             IntPtr value);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_PutByteArray(IntPtr region, IntPtr key,
-                                                                IntPtr value, int length);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Region_GetString(IntPtr region, IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Region_GetByteArray(IntPtr region, IntPtr key,
-                                                                ref IntPtr value, ref int size);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Region_Remove(IntPtr region, IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_ContainsValueForKey(IntPtr region,
-                                                                       IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_DestroyRegion(IntPtr region);
-
-    internal Region(IntPtr regionFactory, string regionName) {
-      var regionNamePtr = Marshal.StringToCoTaskMemUTF8(regionName);
-      _containedObject = apache_geode_RegionFactory_CreateRegion(regionFactory, regionNamePtr);
-      Marshal.FreeCoTaskMem(regionNamePtr);
+    public Region(RegionInterop regionInterop) {
+      _regionInterop = regionInterop;
     }
 
-    public void PutString(string key, string value) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valuePtr = Marshal.StringToCoTaskMemUTF8(value);
-      apache_geode_Region_PutString(_containedObject, keyPtr, valuePtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-      Marshal.FreeCoTaskMem(valuePtr);
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    public TValue Get(TKey key, Object callbackArg) {
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
+      //var byteArray = ObjectToByteArray(key);
+      byte[] bytes = _regionInterop.GetByteArray(key.ToString());
+      return Deserialize<TValue>(bytes);
     }
 
-    public void PutByteArray(string key, byte[] value) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valuePtr = Marshal.AllocCoTaskMem(value.Length);
-      Marshal.Copy(value, 0, valuePtr, value.Length);
-      apache_geode_Region_PutByteArray(_containedObject, keyPtr, valuePtr, value.Length);
-      Marshal.FreeCoTaskMem(keyPtr);
-      Marshal.FreeCoTaskMem(valuePtr);
+    public TValue Get(TKey key) {
+      return Get(key, null);
     }
 
-    public string GetString(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var result =
-          Marshal.PtrToStringUTF8(apache_geode_Region_GetString(_containedObject, keyPtr));
-      Marshal.FreeCoTaskMem(keyPtr);
-      return result;
+    public void Put(TKey key, TValue value, Object callbackArg) {
+      var valueByteArray = ObjectToByteArray(value);
+      _regionInterop.PutByteArray(key.ToString(), valueByteArray);
     }
 
-    public byte[] GetByteArray(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valPtr = (IntPtr)0;
-      int size = 0;
-      apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
-      if (size > 0) {
-        Byte[] byteArray = new Byte[size];
-        Marshal.Copy(valPtr, byteArray, 0, size);
-        Marshal.FreeCoTaskMem(valPtr);
-        return byteArray;
-      } else
-        return null;
+    public void Put(TKey key, TValue value) {
+      Put(key, value, null);
     }
 
-    public void Remove(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      apache_geode_Region_Remove(_containedObject, keyPtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-    }
-
-    public bool ContainsValueForKey(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      bool result = apache_geode_Region_ContainsValueForKey(_containedObject, keyPtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-      return result;
+    byte[] ObjectToByteArray(object obj)
+    {
+      if (obj == null)
+        return null;
+      BinaryFormatter bf = new BinaryFormatter();
+      using (MemoryStream ms = new MemoryStream())
+      {
+        bf.Serialize(ms, obj);
+        return ms.ToArray();
+      }
     }
 
-    protected override void DestroyContainedObject() {
-      apache_geode_DestroyRegion(_containedObject);
-      _containedObject = IntPtr.Zero;
+    private T Deserialize<T>(byte[] param)
+    {
+      using (MemoryStream ms = new MemoryStream(param))
+      {
+        IFormatter br = new BinaryFormatter();
+        return (T)br.Deserialize(ms);
+      }
     }
   }
 }
diff --git a/netcore/netcore-lib/RegionFactory.cs b/netcore/netcore-lib/RegionFactory.cs
index 0cf2fd9..bb992e7 100644
--- a/netcore/netcore-lib/RegionFactory.cs
+++ b/netcore/netcore-lib/RegionFactory.cs
@@ -15,28 +15,38 @@
  * limitations under the License.
  */
 using System;
-using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class RegionFactory : GeodeNativeObject {
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Cache_CreateRegionFactory(IntPtr cache,
-                                                                        int regionType);
 
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_DestroyRegionFactory(IntPtr regionFactory);
+public class RegionFactory<TValue> {
+  RegionFactoryInterop _regionFactoryInterop;
+  RegionInterop _regionInterop;
+  RegionShortcut _regionType;
+  IntPtr _cacheInterop;
+  private CacheInterop cacheInterop;
+  private RegionShortcut regionType;
 
-    internal RegionFactory(IntPtr cache, RegionShortcut regionType) {
-      _containedObject = apache_geode_Cache_CreateRegionFactory(cache, (int)regionType);
-    }
+  public RegionFactory(
+    IntPtr cacheInterop,
+    RegionShortcut regionType) {
+    _regionType = regionType;
+    _cacheInterop = cacheInterop;
+  }
 
-    public Region CreateRegion(string regionName) {
-      return new Region(_containedObject, regionName);
-    }
+  public RegionFactory(CacheInterop cacheInterop, RegionShortcut regionType)
+  {
+    this.cacheInterop = cacheInterop;
+    _cacheInterop = cacheInterop.ContainedObject;
+    this.regionType = regionType;
+  }
 
-    protected override void DestroyContainedObject() {
-      apache_geode_DestroyRegionFactory(_containedObject);
-      _containedObject = IntPtr.Zero;
-    }
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    public IRegion<TKey, TValue> Create<TKey, TValue>(string regionName) {
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
+      _regionFactoryInterop = new RegionFactoryInterop(_cacheInterop, _regionType);
+    _regionInterop = _regionFactoryInterop.CreateRegion(regionName);
+    return new Region<TKey, TValue>(_regionInterop);
   }
 }
+
+}
\ No newline at end of file
diff --git a/netcore/netcore-lib/RegionFactory.cs b/netcore/netcore-lib/RegionFactoryInterop.cs
similarity index 83%
copy from netcore/netcore-lib/RegionFactory.cs
copy to netcore/netcore-lib/RegionFactoryInterop.cs
index 0cf2fd9..1c154ab 100644
--- a/netcore/netcore-lib/RegionFactory.cs
+++ b/netcore/netcore-lib/RegionFactoryInterop.cs
@@ -18,7 +18,7 @@ using System;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class RegionFactory : GeodeNativeObject {
+  public class RegionFactoryInterop : GeodeNativeObject {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_Cache_CreateRegionFactory(IntPtr cache,
                                                                         int regionType);
@@ -26,12 +26,12 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_DestroyRegionFactory(IntPtr regionFactory);
 
-    internal RegionFactory(IntPtr cache, RegionShortcut regionType) {
-      _containedObject = apache_geode_Cache_CreateRegionFactory(cache, (int)regionType);
+    internal RegionFactoryInterop(IntPtr cacheInterop, RegionShortcut regionType) {
+      _containedObject = apache_geode_Cache_CreateRegionFactory(cacheInterop, (int)regionType);
     }
 
-    public Region CreateRegion(string regionName) {
-      return new Region(_containedObject, regionName);
+    public RegionInterop CreateRegion(string regionName) {
+      return new RegionInterop(_containedObject, regionName);
     }
 
     protected override void DestroyContainedObject() {
diff --git a/netcore/netcore-lib/Region.cs b/netcore/netcore-lib/RegionInterop.cs
similarity index 73%
copy from netcore/netcore-lib/Region.cs
copy to netcore/netcore-lib/RegionInterop.cs
index 68d49a5..53a6cc7 100644
--- a/netcore/netcore-lib/Region.cs
+++ b/netcore/netcore-lib/RegionInterop.cs
@@ -17,8 +17,10 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Apache.Geode.Client {
-  public class Region : GeodeNativeObject {
+namespace Apache.Geode.Client
+{
+  public class RegionInterop : GeodeNativeObject
+  {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_RegionFactory_CreateRegion(IntPtr cache,
                                                                          IntPtr regionName);
@@ -48,13 +50,15 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_DestroyRegion(IntPtr region);
 
-    internal Region(IntPtr regionFactory, string regionName) {
+    internal RegionInterop(IntPtr regionFactory, string regionName)
+    {
       var regionNamePtr = Marshal.StringToCoTaskMemUTF8(regionName);
       _containedObject = apache_geode_RegionFactory_CreateRegion(regionFactory, regionNamePtr);
       Marshal.FreeCoTaskMem(regionNamePtr);
     }
 
-    public void PutString(string key, string value) {
+    public void PutString(string key, string value)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valuePtr = Marshal.StringToCoTaskMemUTF8(value);
       apache_geode_Region_PutString(_containedObject, keyPtr, valuePtr);
@@ -62,7 +66,8 @@ namespace Apache.Geode.Client {
       Marshal.FreeCoTaskMem(valuePtr);
     }
 
-    public void PutByteArray(string key, byte[] value) {
+    public void PutByteArray(string key, byte[] value)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valuePtr = Marshal.AllocCoTaskMem(value.Length);
       Marshal.Copy(value, 0, valuePtr, value.Length);
@@ -71,7 +76,21 @@ namespace Apache.Geode.Client {
       Marshal.FreeCoTaskMem(valuePtr);
     }
 
-    public string GetString(string key) {
+    public void PutByteArray(byte[] key, byte[] value)
+    {
+      var keyPtr = Marshal.AllocCoTaskMem(key.Length);
+      Marshal.Copy(key, 0, keyPtr, key.Length);
+
+      var valuePtr = Marshal.AllocCoTaskMem(value.Length);
+      Marshal.Copy(value, 0, valuePtr, value.Length);
+
+      apache_geode_Region_PutByteArray(_containedObject, keyPtr, valuePtr, value.Length);
+      Marshal.FreeCoTaskMem(keyPtr);
+      Marshal.FreeCoTaskMem(valuePtr);
+    }
+
+    public string GetString(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var result =
           Marshal.PtrToStringUTF8(apache_geode_Region_GetString(_containedObject, keyPtr));
@@ -79,34 +98,60 @@ namespace Apache.Geode.Client {
       return result;
     }
 
-    public byte[] GetByteArray(string key) {
+    public byte[] GetByteArray(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valPtr = (IntPtr)0;
       int size = 0;
       apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
-      if (size > 0) {
+      if (size > 0)
+      {
+        Byte[] byteArray = new Byte[size];
+        Marshal.Copy(valPtr, byteArray, 0, size);
+        Marshal.FreeCoTaskMem(valPtr);
+        return byteArray;
+      }
+      else
+        return null;
+    }
+
+    public byte[] GetByteArray(byte[] key)
+    {
+      var keyPtr = Marshal.AllocCoTaskMem(key.Length);
+      Marshal.Copy(key, 0, keyPtr, key.Length);
+
+      var valPtr = (IntPtr)0;
+      int size = 0;
+      apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
+      if (size > 0)
+      {
         Byte[] byteArray = new Byte[size];
         Marshal.Copy(valPtr, byteArray, 0, size);
         Marshal.FreeCoTaskMem(valPtr);
+        Marshal.FreeCoTaskMem(keyPtr);
         return byteArray;
-      } else
+      }
+      else
         return null;
     }
 
-    public void Remove(string key) {
+    public void Remove(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       apache_geode_Region_Remove(_containedObject, keyPtr);
       Marshal.FreeCoTaskMem(keyPtr);
     }
 
-    public bool ContainsValueForKey(string key) {
+    public bool ContainsValueForKey(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       bool result = apache_geode_Region_ContainsValueForKey(_containedObject, keyPtr);
       Marshal.FreeCoTaskMem(keyPtr);
       return result;
     }
 
-    protected override void DestroyContainedObject() {
+    protected override void DestroyContainedObject()
+    {
       apache_geode_DestroyRegion(_containedObject);
       _containedObject = IntPtr.Zero;
     }