ToggleActive <tentity> - 动态设置TEntity </tentity>

时间:2011-11-11 17:42:52

标签: c# reflection

我在C#中有ToggleActive,通常我可以像ToggleActive一样调用它,其中Person是MyProject.Data命名空间中的链接2 sql对象。

我该怎么做这样的事情:ToggleActive&lt;“MyProject.Data.Person”&gt;?有可能吗?我是否以某种方式使用typeof?

谢谢!

更新 - 让我改写这一切。我有一个管理站点,用户可以点击“删除”从不同的linq到sql表的多个记录。

HTML ...

<table class="persons">
    <tr><td>Eric Davis</td><td><a href="/person/delete/14">delete</a></td></tr>
    <tr><td>Tamara Davis</td><td><a href="/person/delete/15">delete</a></td></tr>
</table>

<table class="orders">
    <tr><td>PB & J Sandwich</td><td><a href="/order/delete/6442">delete</a></td></tr>
    <tr><td>Brat Sandwich</td><td><a href="/order/delete/6443">delete</a></td></tr>
</table>

在PersonController中路由......

public ActionResult Delete(int id)
{
    var repository = new MyLinq2SqlRepository();
    repository.DeleteRecord<MyProject.Data.Person>; // MyProject.Data.Person is a linq to sql type
    return redirect("~/"); // return home view
}

在OrderController中路由......

public ActionResult Delete(int id)
{
    var repository = new MyLinq2SqlRepository();
    repository.DeleteRecord<Order>; // this is the only thing different from above action
    return redirect("~/"); // return home view
}

我想要的新功能,ObjectController ...

public ActionResult Delete(int id, string type) {
    var repository = new MyLinq2SqlRepository();
    Type linq2SqlType = Type.GetType(type); // where type = "MyProject.Data.Person" or "MyProject.Data.Order"
    repository.DeleteRecord<linq2SqlType>(id);
    return redirect("~/");
}

这样我可以用于表格......

<table class="persons">
    <tr><td>Eric Davis</td><td><a href="/object/delete/14/MyProject.Data.Person">delete</a></td></tr>
    <tr><td>Tamara Davis</td><td><a href="/object/delete/15/MyProject.Data.Person">delete</a></td></tr>
</table>

Order表看起来非常相似,但链接看起来像这样:

<a href="/object/delete/6442/MyProject.Data.Order">delete</a>

希望我更加清楚我要做的事情!将这些路线行动合并为一种方法。


更新:这就是我最终做到的结果......

HTML ...

<table typeName="@typeof(MyProject.Data.Person)">
@foreach (var p in this.Model.Persons) {
    <tr id="@p.PersonId"><td>@p.FirstName</td><td><a href="#" class="deleteObjLink">delete</a></td></tr>
}
</table>

JS / AJAX ...

$(".deleteObjLink").on('click', function(e) {
    e.preventDefault();
    var link = $(this);
    var id = link.closest("tr").attr("id");
    var typeName = link.closest("table").attr("typeName");
    $.ajax({
        url: '/object/delete', type: 'post', 
        data: JSON.stringify({ id: id, typeName = typeName }), 
        contentType: 'application/json',
        successFunc
    });
});

在MVC对象控制器中......

[HttpPost]    
public JsonResult Delete(int id, string typeName)
{
    Assembly asm = typeof(MyProject.Data.Order).Assembly; // get assembly of any object w/in MyProject.Data.Order namespace (NS). all obj's in that NS share the same assembly
    Type targetEntityType = asm.GetType(typeName);
    MethodInfo genericMethodDefinition = typeof(MyRepository).GetMethod("Delete");
    MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(targetEntityType);
    bool success = (bool)genericMethod.Invoke(myRepo, new object[] { id });

    return this.Json(new { Success = success }, JsonRequestBehavior.DenyGet);
}

MyRepository类具有Delete(int id)方法。

1 个答案:

答案 0 :(得分:1)

如果您尝试使用反射来构建它,则需要使用Type.MakeGenericType来组合相应的类型。

这看起来像是:

string typeName = "MyProject.Data.Person";
Type toggleActiveType = typeof(ToggleActive<>);
Type[] typeArgs = new[]{ Type.GetType(typeName) };

Type fullyDefinedType = toggleActiveType.MakeGenericType(typeArgs);

// Use fullyDefinedType as needed

编辑:

鉴于您的编辑,目标是调用泛型方法,而不是泛型类型。这是通过MethodInfo.MakeGenericMethod完成的,如下所示:

var repository = new MyLinq2SqlRepository();
string typeName = "MyProject.Data.Person";
var mi = repository.GetType().GetMethod("DeleteRecord");
var fullyDefinedMethod = mi.MakeGenericMethod(Type.GetType(typeName));

object[] parameters = new[] { id };
fullyDefinedMethod.Invoke(repository, parameters);