Я предлагаю добавить конструктор без параметров в форму Form1, чтобы вы могли вызвать его после из внешней сборки, которая может не знать, какое количество параметров она ожидает (если есть), и добавить logi c, необходимые для обработки null
параметры.
namespace XMLValidator
{
public partial class Main : Form
{
public Main() : this(null) { }
public Main(string[] args) {
InitializeComponent();
[Something] = args;
}
}
}
После этого, если вы не хотите / не можете использовать интерфейсы (чтобы иметь общее понимание контракта между этими сборками), у вас есть полагаться на свои знания о том, какие формы вы хотите загрузить, и вызывать их с помощью Name
.
Параметры могут быть переданы с помощью перегрузки Activator.CreateInstance , которая принимает тип (вы знаете, что тип, который вы хотите загрузить, форма) и аргументы в форме params object[]
.
public static object CreateInstance (Type type, params object[] args);
Каждый объект в params
представляет аргументы, ожидаемые конструктором указанного вами класса. Конструктор без параметров не ожидает никаких аргументов, поэтому вы передаете null
в args[0]
. В противном случае args[0]
содержит аргументы непустого конструктора, который вы хотите вызвать, для инициализации указанного класса.
object[] args = new object[1] { new string[] { "Args String", "Args Value", "Other args" } };
и вызовите:
Activator.CreateInstance([Type], args) as [Type];
Я предлагаю построить промежуточный класс, который обрабатывает инициализацию внешней сборки, автоматически извлекает некоторую полезную информацию (NameSpace
, ресурсы определенного типа c - Forms
, ресурсы проекта и др. c.). поэтому вам просто нужно указать имя формы для ее активации и отображения.
Например, из меню в вашей MDIParent Form:
public partial class MDIParent : Form
{
private ResourceBag formResources = null;
public MDIParent()
{
InitializeComponent();
formResources = new ResourceBag([Assembly Path]);
}
// [...]
// From a ToolStrip MenuItem, load with arguments
private void loadExternalFormToolStripMenuItem_Click(object sender, EventArgs e)
{
object[] args = new object[1] { new string[] { "Args String", "Args Value", "Other args" } };
Form form1 = formResources.LoadForm("Form1", args);
form1.MdiParent = this;
form1.Show();
}
// From another ToolStrip MenuItem, load using the default Constructor
private void loadExternalFormNoParamsToolStripMenuItem_Click(object sender, EventArgs e)
{
Form form1 = formResources.LoadForm("Form1");
form1.MdiParent = this;
form1.Show();
}
}
Помощник ResourceBag
class :
Возможно, добавьте перегрузку в public Form LoadForm()
, чтобы передать другой NameSpace
, если вы хотите загрузить объект класса, который не является частью значения по умолчанию NameSpace
.
using System.IO;
using System.Reflection;
using System.Windows.Forms;
internal class ResourceBag
{
private string m_AssemblyName = string.Empty;
private static Assembly asm = null;
public ResourceBag() : this(null) { }
public ResourceBag(string assemblyPath)
{
if (!string.IsNullOrEmpty(assemblyPath)) {
this.AssemblyName = assemblyPath;
}
}
public string NameSpace { get; set; }
public string AssemblyName {
get => m_AssemblyName;
set {
if (File.Exists(value)) {
m_AssemblyName = value;
asm = Assembly.LoadFrom(m_AssemblyName);
this.NameSpace= asm.GetName().Name;
}
else {
throw new ArgumentException("Invalid Assembly path");
}
}
}
public Form LoadForm(string formName, params object[] args)
{
if (asm == null) throw new BadImageFormatException("Resource Library not loaded");
return Activator.CreateInstance(asm.GetType($"{NameSpace}.{formName}"), args) as Form;
}
}