如何在不使用“new”关键字的情况下发起课程?

时间:2013-07-30 15:13:22

标签: c# asp.net-mvc-4 razor

这可能是一个愚蠢的问题,但我正在开发一个组件,我有一个类,其属性如下

public class Grid()
{
 ..
 public IDecorator Decorator { get; set;}

}

我想要的是让用户以下列方式指定自己的实现IDecorator的自定义类

...BuildGrid(
grid=>{
..
grid.Decorator =  [CustomNameSpace].[DecoratorClass] 
//as in 
grid.Decorator =  Com.MyCompany.DivDecorator
..
});

Com.MyCompany.DivDecorator实现了IDecorator接口。那么如果没有最终用户在

中指定“new”关键字,我应该怎么做呢
grid.Decorator = new Com.MyCompany.DivDecorator();

我知道我在这里错过了一些关键的c#概念。

由于

[编辑]

我试图做像这里的Java DisplayTag库那样的事情

http://www.displaytag.org/1.2/tut_decorators.html

他们这样做的方式是

... decorator="org.displaytag.sample.Wrapper"

所以我想而不是

public IDecorator Decorator { get; set;}

我应该做

public String Decorator (get; set;}

然后在内部使用TypeOf()来解决它....只是想知道是否有任何其他方式优雅地在C#中执行它。

由于

5 个答案:

答案 0 :(得分:8)

您可以使用工厂方法:

public class DivDecorator
{
    public static IDecorator Create()
    {
        return new Com.MyCompany.DivDecorator()
    }
}

...

grid.Decorator = Com.MyCompany.DivDecorator.Create();

或单身人士:

public class DivDecorator
{
    public static readonly IDecorator Instance = new DivDecorator();
}

...

grid.Decorator = Com.MyCompany.DivDecorator.Instance;

在这两种情况下,您只是将new运算符移动到其他位置。

或者,您可以让用户指定类型,然后您需要担心在需要时实例化它:

public class Grid
{
    public Type DecoratorType { get; set; }

    private IDecorator CreateDecorator()
    {
        return (IDecorator)Activator.CreateInstance(this.DecoratorType);
    }
}

...

grid.Decorator = typeof(Com.MyCompany.DivDecorator);

甚至更好,使用泛型:

public class Grid<T> where T : IDecorator, new
{
    private T CreateDecorator()
    {
        return new T();
    }
}

BuildGrid<Com.MyCompany.DivDecorator>(grid => ... );

答案 1 :(得分:5)

如果我理解你在寻找什么,你可以使用通用:

public class Grid<TDecorator> where TDecorator : IDecorator, new() {

    private readonly TDecorator _decorator;

    public Grid() {
        _decorator = new TDecorator();
    }

    public TDecorator Decorator { get { return _decorator; } }
}

他们通过调用得到一个网格:

var myGrid = new Grid<MyDecorator>();

答案 2 :(得分:3)

您可以使BuildGrid通用,并指定new()约束。

e.g。 BuildGrid<T>() where T : IDecorator, new()

虽然我并不是100%明白你想要的东西。

答案 3 :(得分:1)

鉴于您有一个界面,您将在某处创建一个实例。 您可以注入它(请参阅IOC模式或实例工厂模式)

有各种各样的场景。 但要理解factory patterns will help

1)该类在程序集内部。 发现类型 Getting all types that implement an interface 并创建一个实例 http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

2)代码是外部的,     http://msdn.microsoft.com/en-us/library/dd460648.aspx

3)或文件 http://msdn.microsoft.com/en-us/library/system.reflection.assembly.load%28v=vs.110%29.aspx

答案 4 :(得分:0)

感谢所有帮助过我的人!我决定使用p.s.w.g的Activator.CreateInstance方法。原因是,对于Grid Component,我有一个表级Decorator,然后是网格的每一列,也可以有自己的装饰器。如在

@Model.[MyIEnumberable].BuildGrid<Product>(grid=>{
grid.ShowHeader = false;
grid.CellSpacing = 0;
grid.CellPadding = 0;
grid.Decorator = "Com.MyCompany.DivDecorator";
grid.columns(
        grid.column(HeaderText: "First Column", Decorator:"Com.MyCompany.FirstColumnDecorator"...),
        grid.column(HeaderText: "Second Column", Decorator:"Com.MyCompany.SecondColumnDecorator"..),
        grid.column(HeaderText: "ThirdColumn", Text:@item.ProductID),
        grid.column(HeaderText: "ThirdColumn", Text:@item.[A Property only exist in grid.Decorator, achieved using dynamic/DynamicObject])
)
})

所以考虑到我的情况,因为每个列都有可能有自己的装饰器类。所以我将不得不使用Activator.CreateInstance。

再次感谢大家的帮助!!再次非常感谢你的时间!!

[编辑]。在阅读p.s.w.g的最后两条评论之后,可以采用泛型方法!