Próbuję utworzyć proste narzędzie do raportowania, w którym użytkownik może wybierać z zestawu wskaźników KPI, wykresów, funkcji zagregowanych i innych parametrów, kliknąć przycisk, po czym usługa wcf jest wywoływana, a następnie zwraca niestandardowy model ze wszystkimi danymi. Następnie można go wyświetlić w aplikacji MVC/WPF (może to być jedno i drugie).Ogólne interfejsy dla raportu półdokładowego
Ponieważ użytkownicy mogą pochodzić z wielu krajów, chcę użyć adnotacji danych, aby wyodrębnić wszystkie numery i nagłówki w sposób dostosowany do formatu językowego i liczbowego, do którego przyzwyczaił się bieżący użytkownik.
Ładowanie danych i wszystko to działa dobrze, bez problemu. Używam też adnotacji do danych, więc wszystkie ustawienia dotyczące języka/kultury są zadbane. Problemy pojawiają się, gdy próbuję umieścić wszystkie dane w modelu, który chcę wyświetlić użytkownikowi.
Co próbuję zrobić, to klasa Report, która zawiera kolekcję kolumn. Każda kolumna może być listą wartości int/double/... Teraz, od kiedy mam do czynienia z WCF i powyższe wyjaśnienie implikuje (o ile rozumiem) użycie generycznych, zakładam, że mogę użyć [KnownType] lub [ServiceKnownType] dla klas/wcf operacji, podczas gdy faktycznie używając typ bazowy lub interfejs jako wartość zwracana. Nigdy tak naprawdę nie próbowałem tego, ale znalazłem kilka dobrych wyjaśnień, które wydają mi się logiczne, więc zakładam, że nie będę miał dużych problemów w tej części (przynajmniej mam taką nadzieję).
Teraz moje interfejsy są jako takie (uproszczony skupić się na rzeczywisty problem mam):
public interface IReport<T> where T: IConvertible { ICollection<IColumn<T>> Columns { get; set; } }
public interface IColumn<T> where T: IConvertible { ICollection<IValue<T>> Values { get; set; } }
public interface IValue<T> where T: IConvertible { T Value { get; set; } }
Ponieważ wartość w każdej kolumnie może być int/double/... Zakładam muszę mieć rzeczywistą klasę tylko dla wartości (nie sądzę, można użyć atrybutu adnotacji dane na temat rodzaju zbiórki), takie jak:
public class IntValue: IValue<int>
{
[DisplayFormat(DataFormatString = "{0:#,##0;-#,##0;'---'}", ApplyFormatInEditMode = true)]
public int Value { get; set; }
}
oczywiście, że wygląda dziwnie, bo może po prostu sprawiają, że jest to klasa ogólna Wartość, która implementuje IValue i zostanie z nią wykonana, ale jeśli zrobię to głupie i utwórz klasę dla każdego możliwego typu (teraz, kiedy ją rozpisuję, to brzmi naprawdę źle, wiem), mogę użyć atrybutu DisplayFormat i nie muszę się martwić o sposób, w jaki będzie on prezentowany użytkownikowi, to " Zawsze będę odpowiedni.
Teraz dla klas, które implementują iColumn i iReport, że jest prosta:
public class Report<T>: IReport<T> where T: IConvertible
{
public ICollection<IColumn<T>> Columns { get; set; }
public Report() { Columns=new List<IColumn<T>>(); }
}
public class Column<T>: IColumn<T> where T: IConvertible
{
public ICollection<IValue<T>> Values { get; set; }
public Column() { Values = new List<IValue<T>>(); }
}
Z listy interfejsów i klas, od razu widać, że to sprawia, że niemożliwe, aby mieć raport, gdzie niektóre kolumny mieć inne typy. Więc nie jest możliwe utworzenie raportu, w którym niektóre kolumny są int, niektóre są podwójne, ... Ponieważ ogólne ograniczenie w IReport pozwala określić typ, utkniesz z tym dla wszystkich kolumn, ponieważ propaguje się do wartości każda kolumna ... I tego właśnie chcę naprawdę.
Czuję, że nigdzie się nie dostaję, a prawdopodobnie brakuje mi czegoś naprawdę prostego, więc doceniłbym szturchnięcie we właściwym kierunku.
TL; DR: Jak uzyskać ogólną kolekcję w typie nietypowym?
Nie możesz utworzyć raportu jako 'nowy IReport'? –
Baldrick
O ile widzę teraz, to nie pozwala mi dodać int lub podwójnej kolumny, ponieważ oczekuje, że będą one IConvertible, a nie JAKIEKOLWIEK klasę wykonawczą IConvertible. –