我有一个界面
using ClassAbstractFactory;
public interface IPlugin
{
AbstractFactory GetFactory();
}
Run Code Online (Sandbox Code Playgroud)
和一个AbstractFactory
public abstract class AbstractFactory
{
public abstract AbstractCake CreateCake();
public abstract AbstractBox CreateBox();
}
public abstract class AbstractCake
{
public abstract void Interact(AbstractBox box);
}
public abstract class AbstractBox
{
}
Run Code Online (Sandbox Code Playgroud)
我有继承AbstractCake的.dll
public class ChocolateCake : AbstractCake
{
private bool _isPacked;
private bool _isDecorated;
private string _nameOfCake;
public ChocolateCake()
{
_isPacked = false;
_isDecorated = false;
_nameOfCake = "??????????";
}
public bool IsPacked
{
get { return _isPacked; }
}
public bool IsDecorated
{
get { return _isDecorated; }
}
public string NameOfCake { get; set; }
public override void Interact(AbstractBox box)
{
_isPacked = true;
}
}
Run Code Online (Sandbox Code Playgroud)
我像这样加载DLL:
public IPlugin LoadAssembly(string assemblyPath)
{
Assembly ptrAssembly = Assembly.LoadFile(assemblyPath);
foreach (Type item in ptrAssembly.GetTypes())
{
if (!item.IsClass) continue;
if (item.GetInterfaces().Contains(typeof(IPlugin)))
{
return (IPlugin)Activator.CreateInstance(item);
}
}
throw new Exception("Invalid DLL, Interface not found!");
}
List<IPlugin> list = new List<IPlugin>();
foreach (var assemblyPath in GetPathsListToDll())
{
list.Add(LoadAssembly(assemblyPath));
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能在我的ChocolateCake中获取属性,就像使用它们一样
foreach (var str in list)
{
Boolean a = str.GetFactory().GetCake().CreateCake().IsPacked;
}
Run Code Online (Sandbox Code Playgroud)
或者像这样
string a = str.GetFactory().GetCake().CreateCake().NameOfCake;
Run Code Online (Sandbox Code Playgroud)
或者像这样
str.GetFactory().GetCake().CreateCake().NameOfCake("Something");
Run Code Online (Sandbox Code Playgroud)
或者像这样
str.GetFactory().GetCake().CreateCake().IsDecorated(true);
Run Code Online (Sandbox Code Playgroud)
这里的问题是,AbstractFactory有一个返回的方法AbstractCake,并且AbstractCake本身没有属性可言.就目前而言,您需要将Cake(直接或as关键字)ChocolateCake转发到访问其任何属性之前,这非常麻烦:
string a = (ChocolateCake)(str.GetFactory().CreateCake()).NameOfCake;
Run Code Online (Sandbox Code Playgroud)
以下是一些注意事项:
AbstractCake,例如NameOfCake,IsPacked和IsDecoratedAbstractFactory和AbstractCake类根本没有任何实现,请考虑将这些更改为接口而不是抽象类,即ICakeFactory和ICake.具体实现将ChocolateCakeFactory和ChocolateCake以前一样.ICakeFactory,ICake和IBox),并且不需要做任何停机铸造或做任何假设对实际的具体类型蛋糕等.即
public interface ICake
{
void Interact(IBox box);
bool IsPacked { get; }
bool IsDecorated { get; }
string NameOfCake { get; set; }
}
public class ChocolateCake : ICake
{
private bool _isPacked;
private bool _isDecorated;
private string _nameOfCake;
public ChocolateCake() // ctor is not on the interface and is implementation detail
{
_isPacked = false;
_isDecorated = false;
_nameOfCake = "??????????";
}
public void Interact(IBox box) {...}
public bool IsPacked { get { return _isPacked; } }
public bool IsDecorated { get { return _isDecorated; } }
// ...
}
public interface ICakeFactory
{
ICake CreateCake();
IBox CreateBox();
}
public class ChocolateCakeFactory : ICakeFactory
{
public ICake CreateCake() {return new ChocolateCake();}
public IBox CreateBox() {return new ChocolateCakeBox();}
}
Run Code Online (Sandbox Code Playgroud)
回复:用法
你不可能做到这一点:
string a = str.GetFactory().GetCake().CreateCake().NameOfCake;
str.GetFactory().GetCake().CreateCake().NameOfCake = "Something"; // Prop setter
Run Code Online (Sandbox Code Playgroud)
因为这会每次创建一个新的蛋糕实例(并丢弃实例).怎么样:
class Bakery
{
private readonly ICakeFactory _cakeFactory;
public Bakery(ICakeFactory cakeFactory)
{
Contract.Requires(cakeFactory != null);
cakeFactory = _cakeFactory;
}
bool BakeStuff()
{
var cake = _cakeFactory.CreateCake();
cake.NameOfCake = "StackOverflow";
return cake.IsDecorated && cake.IsPacked;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑,重新提升更改事件
public interface ICake : INotifyPropertyChanged
Run Code Online (Sandbox Code Playgroud)
然后你可以提高你的可变属性,例如
public string NameOfCake
{
get { return _nameOfCake} ;
set {
var propChanged = PropertyChanged;
if (propChanged != null && value != _nameOfCake)
{
propChanged(this, new PropertyChangedEventArgs("NameOfCake"));
}
_nameOfCake = value;
}
}
Run Code Online (Sandbox Code Playgroud)
订阅就像这样
var cake = new ChocolateCake();
cake.PropertyChanged += (sender, eventArgs)
=> Console.WriteLine("Property {0} has changed", eventArgs.PropertyName);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
124 次 |
| 最近记录: |