-2

I have a bunch of code doing the same thing but with just a few changes... Sounds like a great option for building a method to do the work for all of them. I need to use a class name and couldn't find anything simular enough to think I should try it - this was the closest How to use class name as parameter in C#

My classes ImportUserNotificationListModel implement interfaces with generics that have caused me a few issues in some other areas so this might be a bit harder because of that.

  public class ImportNotificationRoleListModel : IImportListBase<ImportNotificationRoleModel>, IImportListDatabaseCalls<ImportNotificationRoleModel>

and

  public class ImportUserNotificationListModel : IImportListBase<ImportUserNotificationModel>, IImportListDatabaseCalls<ImportUserNotificationModel>

here is the code I wish to not duplicate:

 private static bool SaveUserNotification(XDocument xdoc, int importID, SqlConnection cn, SqlTransaction tran)
    {
        try
        {

var SourceInfo = xdoc.Root.Element("UserNotifications").ToString();
            XmlSerializer serializer = new XmlSerializer(typeof(ImportUserNotificationListModel));

            using (TextReader reader = new StringReader(SourceInfo))
            {
                ImportUserNotificationListModel Listresult = (ImportUserNotificationListModel)serializer.Deserialize(reader);

                foreach (ImportUserNotificationModel lim in Listresult.ImportItems)
                {


                    Listresult.SaveImportToDatabase(lim, importID, cn, tran);
                }

                return true;

            }
        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }


        return false;
    }

Here is the copy (I have about 12 that do this)

 private static bool SaveNotificationRoles(XDocument xdoc, int importID, SqlConnection cn, SqlTransaction tran)
    {
        try
        {

            var SourceInfo = xdoc.Root.Element("NotificationRoles").ToString();
            XmlSerializer serializer = new XmlSerializer(typeof(ImportNotificationRoleListModel));

            using (TextReader reader = new StringReader(SourceInfo))
            {
                ImportNotificationRoleListModel Listresult = (ImportNotificationRoleListModel)serializer.Deserialize(reader);

                foreach (ImportNotificationRoleModel lim in Listresult.ImportItems)
                {


                    Listresult.SaveImportToDatabase(lim, importID, cn, tran);
                }

                return true;

            }
        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }


        return false;
    }
Community
  • 1
  • 1
Brian Hanf
  • 544
  • 2
  • 11
  • 31

1 Answers1

1

This compiles:

private static bool Save<T, T2>(XDocument xdoc, 
        int importID, SqlConnection cn, SqlTransaction tran, String elementName)
  where T: IImportListBase<T2>, IImportListDatabaseCalls<T2>
  where T2 : IImportBase
{
    try
    {
        var SourceInfo = xdoc.Root.Element(elementName).ToString();

        XmlSerializer serializer = new XmlSerializer(typeof(T));

        using (TextReader reader = new StringReader(SourceInfo))
        {
            T Listresult = (T)serializer.Deserialize(reader);

            foreach (T2 lim in Listresult.ImportItems)
            {
                Listresult.SaveImportToDatabase(lim, importID, cn, tran);
            }

            return true;
        }
    }
    catch (Exception e)
    {
        Console.Write(e.Message);
    }

    return false;
}

But you have to give it both type parameters explicitly when you call it, plus the element name:

Save<ImportNotificationRoleListModel, ImportNotificationRoleModel>(
    null, 0, null, null, "NotificationRoles");

Save<ImportUserNotificationListModel, ImportUserNotificationModel>(
    null, 0, null, null, "UserNotifications");

I bet somebody smart could do better.