我有两节课:
public class DefaultMachineSettings : MachineSettings
{
private static DefaultMachineSettings instance;
private DefaultMachineSettings() { }
public static DefaultMachineSettings getInstance()
{
if (instance == null)
instance = new DefaultMachineSettings();
return instance;
}
public static void destroyInstance()
{
instance = null;
}
}
第二课:
public class Sani80100Settings : MachineSettings
{
private static Sani80100Settings instance;
private Sani80100Settings()
{
setDefaultMachineXML(true);
}
public static Sani80100Settings getInstance()
{
if (instance == null)
instance = new Sani80100Settings();
return instance;
}
public void setDefaultMachineXML(Boolean overrideValue)
{
Dictionary<String, String> defaultXML = new Dictionary<string, string>();
defaultXML.Add("WZ1_Beschreibung", "Trennwerkzeug");
defaultXML.Add("WZ1_Offset", "0");
defaultXML.Add("WZ1_WirkungsbereichLinks", "2.5");
defaultXML.Add("WZ1_WirkungsbereichRechts", "2.5");
defaultXML.Add("WZ2_Beschreibung", "Aufzugband/Omega");
defaultXML.Add("WZ2_Offset", "-118");
defaultXML.Add("WZ2_WirkungsbereichLinks", "0");
defaultXML.Add("WZ2_WirkungsbereichRechts", "0");
defaultXML.Add("WZ3_Beschreibung", "Doppelloch Abspannung");
defaultXML.Add("WZ3_Offset", "-250.1");
defaultXML.Add("WZ3_WirkungsbereichLinks", "0");
defaultXML.Add("WZ3_WirkungsbereichRechts", "0");
defaultXML.Add("WZ4_Beschreibung", "Zusätzliche Abspannung");
defaultXML.Add("WZ4_Offset", "-380");
defaultXML.Add("WZ4_WirkungsbereichLinks", "0");
defaultXML.Add("WZ4_WirkungsbereichRechts", "0");
defaultXML.Add("Vorschub60", "100");
defaultXML.Add("LamellenlaengeSoll60", "1998.5");
defaultXML.Add("LamellenlaengeIst60", "2000");
defaultXML.Add("Vorschub80", "100");
defaultXML.Add("LamellenlaengeSoll80", "2000.5");
defaultXML.Add("LamellenlaengeIst80", "2000");
defaultXML.Add("Vorschub100", "100");
defaultXML.Add("LamellenlaengeSoll100", "2003");
defaultXML.Add("LamellenlaengeIst100", "2000");
config.setDefaultXml(defaultXML, overrideValue);
}
}
基类:
public class MachineSettings : SettingsBase
{
protected MachineSettings() : base()
{
ClientSettings clientSettings = ClientSettings.getInstance();
String path = ConfigPath + "machines\\";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Machine.Name machineName;
//Hier wird überprüft, ob die SAP Maschine ein Äquivalent in Apertum hat um die gleiche Konfigurationsdatei zu verwenden.
switch (clientSettings.MachineName)
{
case Machine.Name.SANI8_10:
machineName = Machine.Name.A7660_01;
break;
default:
machineName = clientSettings.MachineName;
break;
}
String fileName = machineName + "_" + Environment.UserName + ".xml";
restoreTempConfig("machines\\" + fileName);
config = new ConfigXml(path + fileName);
setDefaultXML();
}
}
SettingsBase
public abstract class SettingsBase
{
public ConfigXml config;
public const String CHARACTERISTIC_PREFIX = "#c#";
private readonly static String NetworkPath = @"\\dc2\Programmdaten$\" + Environment.MachineName.ToUpper() + @"\Maschinenclient\";
private readonly static String TempPath = Path.GetTempPath() + @"\Maschinenclient\";
public String ConfigPath;
public static Boolean TEMPPATHSAVING = false;
public SettingsBase()
{
if (!Directory.Exists(NetworkPath))
{
try
{
Directory.CreateDirectory(NetworkPath);
ConfigPath = NetworkPath;
}
catch (UnauthorizedAccessException)
{
ConfigPath = TempPath;
}
catch
{
ConfigPath = TempPath;
}
}
else
{
if (WriteAccess(NetworkPath))
ConfigPath = NetworkPath;
else
ConfigPath = TempPath;
}
if (ConfigPath == TempPath)
{
if (!Directory.Exists(TempPath))
Directory.CreateDirectory(TempPath);
TEMPPATHSAVING = true;
}
else
TEMPPATHSAVING = false;
}
public void restoreTempConfig(String fileName)
{
if (ConfigPath == NetworkPath)
{
if (File.Exists(TempPath + fileName))
{
if (!File.Exists(NetworkPath + fileName))
File.Copy(TempPath + fileName, NetworkPath + fileName, false);
File.Delete(TempPath + fileName);
}
}
}
private Boolean WriteAccess(String path)
{
try
{
path = path + DateTime.Now.ToString("yyyyMMddHHmmssffff") + Environment.MachineName.ToUpper() + Environment.UserName + ".access";
FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
streamWriter.WriteLine("ACCESS GRANTED");
}
fileStream.Close();
File.Delete(path);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
catch
{
return false;
}
}
}
是否有可能只有一个基类MachineSettings
的实例?
这意味着DefaultMachineSettings
和Sani80100Settings
应使用相同的MachineSettings
实例
我google了很多,但没有得到线索。
有人知道解决方案吗?
招呼
答案 0 :(得分:4)
如果您要使用继承,那么DefaultMachineSettings
或Sani80100Settings
的每个实例都将继承自己的MachineSettings
。
如果你需要有两个具有相同base
实例的单例实例(来自不同的类),那么你需要使用聚合,而不是继承。
类似的东西:
public class FirstClass
{
private static FirstClass instance;
private FirstClass(BaseClass baseInstance) { /* store baseInstance somewhere */ }
public static FirstClass getInstance()
{
if (instance == null)
instance = new FirstClass(BaseClass.getInstance());
return instance;
}
}
public class SecondClass
{
private static SecondClass instance;
private SecondClass(BaseClass baseInstance) { /* store baseInstance somewhere */ }
public static SecondClass getInstance()
{
if (instance == null)
instance = new Second(BaseClass.getInstance());
return instance;
}
}
public class BaseClass
{
private static BaseClass instance;
private BaseClass() {}
public static BaseClass getInstance()
{
if (instance == null)
instance = new BaseClass();
return instance;
}
}
在这种情况下,您将无法使用protected
中的任何BaseClass
成员。
更新1
使用Autofac的示例:
using System;
using Autofac;
namespace DemoApp
{
public class Program
{
private static IContainer Container { get; set; }
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// register your base class
builder.RegisterType<BaseClass>() // register base class
.AsSelf() // register as `BaseClass` (without any interfaces)
.SingleInstance(); // register as a singleton
// register all your child classes
builder.RegisterType<FirstClass>()
.AsSelf()
.SingleInstance();
builder.RegisterType<SecondClass>()
.AsSelf()
.SingleInstance();
// or you can do the following
// get the assembly
var dataAccess = Assembly.GetExecutingAssembly();
// and register all classes which ends with 'Settings' as singletons
builder.RegisterAssemblyTypes(dataAccess)
.Where(t => t.Name.EndsWith("Settings"))
.AsSelf()
.SingleInstance();
Container = builder.Build();
// The DoWorkmethod is where we'll make use
// of our dependency injection.
DoWork();
}
public static void WriteDate()
{
// Create the scope, resolve your FirstClass,
// use it, then dispose of the scope.
using (var scope = Container.BeginLifetimeScope())
{
var firstClass = scope.Resolve<FirstClass>();
firstClass.SomeMethodOrWhatever();
}
}
}
}
希望它会有所帮助。