ToggleActive — динамически устанавливаемый TEntity

#c# #reflection

#c# #отражение

Вопрос:

У меня есть ToggleActive в C #, и обычно я могу называть его как ToggleActive, где Person — это sql-объект link 2 в MyProject.Пространство имен данных.

Как я могу сделать что-то вроде этого: ToggleActive<«MyProject.Data.Person»>? Возможно ли что-то подобное? Использую ли я typeof каким-либо образом?

Спасибо!

ОБНОВЛЕНИЕ — позвольте мне перефразировать все это. У меня есть сайт администратора, где пользователи могут нажать «Удалить» для нескольких записей из разных таблиц linq to 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 amp; 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>
  

И таблица заказов выглядела бы очень похоже, но ссылки выглядели бы следующим образом:

 <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:

Если вы пытаетесь использовать отражение для создания этого, вам нужно будет использовать 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);
  

Комментарии:

1. Спасибо! Так это становится, ToggleActive<fullyDefinedType>?

2. @IanDavis Это становится typeof(ToggleActive<fullyDefinedType>) , который вы можете затем использовать с отражением, чтобы делать то, что вы хотите. Например, если вы хотите создать экземпляр, вы могли бы использовать это в качестве аргумента Activator . CreateInstance: msdn.microsoft.com/en-us/library/wccyzw83.aspx

3. итак, ToggleActive<> является частью объекта репозитория. Я пытаюсь… MyRepo repo = new MyRepo(); затем… Введите toggleActiveType = typeof(репозиторий. ToggleActive<>) и я получаю сообщение об ошибке: «repo — это «поле», но оно используется как «опечатка»». есть мысли? Спасибо!

4. @IanDavis Я думаю, вам нужно предоставить больше информации о том, что вы пытаетесь сделать… Здесь нет особого смысла..

5. @IanDavis Я просто показал тебе, чего ты хочешь, я думаю… Вы спрашивали о типах, но вам нужна общая информация о методе.