--- /dev/null
+/*
+* Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Loader;
+
+namespace Tizen.NUI
+{
+ internal class NUIGadgetAssemblyLoadContext : AssemblyLoadContext
+ {
+ public NUIGadgetAssemblyLoadContext() : base(isCollectible: true)
+ {
+ }
+
+ protected override Assembly Load(AssemblyName name)
+ {
+ return null;
+ }
+ }
+
+ internal class NUIGadgetAssembly
+ {
+ private static readonly object _assemblyLock = new object();
+ private readonly string _assemblyPath;
+ private WeakReference _assemblyRef;
+ private Assembly _assembly = null;
+
+ public NUIGadgetAssembly(string assemblyPath) { _assemblyPath = assemblyPath; }
+
+ public void Load()
+ {
+ lock (_assemblyLock)
+ {
+ if (_assembly != null)
+ {
+ return;
+ }
+
+ Log.Warn("Load(): " + _assemblyPath + " ++");
+ NUIGadgetAssemblyLoadContext context = new NUIGadgetAssemblyLoadContext();
+ _assemblyRef = new WeakReference(context);
+ using (MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(_assemblyPath)))
+ {
+ _assembly = context.LoadFromStream(memoryStream);
+ }
+ Log.Warn("Load(): " + _assemblyPath + " --");
+ }
+ }
+
+ public bool IsLoaded { get { return _assembly != null; } }
+
+ public NUIGadget CreateInstance(string className)
+ {
+ lock (_assemblyLock)
+ {
+ return (NUIGadget)_assembly?.CreateInstance(className);
+ }
+ }
+
+ public void Unload()
+ {
+ lock (_assemblyLock)
+ {
+ if (_assembly == null)
+ {
+ return;
+ }
+
+ Log.Warn("Unload(): " + _assemblyPath + " ++");
+ if (_assemblyRef.IsAlive)
+ {
+ (_assemblyRef.Target as NUIGadgetAssemblyLoadContext).Unload();
+ }
+
+ _assembly = null;
+ Log.Warn("Unload(): " + _assemblyPath + " --");
+ }
+ }
+ }
+}
\ No newline at end of file
internal string ResourceClassName { get; set; }
- internal Assembly Assembly { get; set; }
+ internal NUIGadgetAssembly Assembly { get; private set; }
internal static NUIGadgetInfo CreateNUIGadgetInfo(string packageId)
{
Log.Warn("Failed to destroy package info. error = " + errorCode);
}
+ info.Assembly = new NUIGadgetAssembly(info.ResourcePath + info.ExecutableFile);
return info;
}
}
using Tizen.Applications;
using System.ComponentModel;
using System.Runtime.InteropServices;
+using System.Runtime.Loader;
using System.Reflection;
using System.Threading.Tasks;
+using System.Security.AccessControl;
namespace Tizen.NUI
{
}
NUIGadgetInfo info = Find(resourceType);
+ Load(info);
+ }
+
+ private static void Load(NUIGadgetInfo info)
+ {
+ if (info == null)
+ {
+ throw new ArgumentException("Invalid argument");
+ }
+
try
{
- Load(info);
+ lock (info)
+ {
+ if (!info.Assembly.IsLoaded)
+ {
+ info.Assembly.Load();
+ }
+ }
}
catch (FileLoadException e)
{
throw new InvalidOperationException(e.Message);
}
+ catch (BadImageFormatException e)
+ {
+ throw new InvalidOperationException(e.Message);
+ }
}
- private static void Load(NUIGadgetInfo info)
+ /// <summary>
+ /// Unloads the loaded assembly of the NUIGadget.
+ /// </summary>
+ /// <param name="resourceType">The resource type of the NUIGadget package.</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of a invalid argument.</exception>
+ /// <since_tizen> 11 </since_tizen>
+ public static void Unload(string resourceType)
+ {
+ if (string.IsNullOrEmpty(resourceType))
+ {
+ throw new ArgumentException("Invalid argument");
+ }
+
+ NUIGadgetInfo info = Find(resourceType);
+ Unload(info);
+ }
+
+ private static void Unload(NUIGadgetInfo info)
{
if (info == null)
{
lock (info)
{
- if (info.Assembly == null)
+ if (info.Assembly.IsLoaded)
{
- Log.Warn("NUIGadgetAssembly.Load(): " + info.ResourcePath + info.ExecutableFile + " ++");
- info.Assembly = Assembly.Load(File.ReadAllBytes(info.ResourcePath + info.ExecutableFile));
- Log.Warn("NUIGadgetAssembly.Load(): " + info.ResourcePath + info.ExecutableFile + " --");
+ info.Assembly.Unload();
}
}
}
}
NUIGadgetInfo info = Find(resourceType);
- try
- {
- Load(info);
- }
- catch (FileLoadException e)
- {
- throw new InvalidOperationException(e.Message);
- }
+ Load(info);
- NUIGadget gadget = info.Assembly.CreateInstance(className, true) as NUIGadget;
+ NUIGadget gadget = info.Assembly.CreateInstance(className);
if (gadget == null)
{
throw new InvalidOperationException("Failed to create instance. className: " + className);