Thanks for that, and the feedback from everyone else as well.

Basically, we'll be exposing a GetReport() service operation using WCF.

We've defined the following types in XML Schema:

ReportType (base)
 - BillableHoursReportType
 - DetailByEmployeeReportType
 - DetailByDateReportType

then used svcutil to generate the data contract classes.

At our data layer, we used LINQ to SQL, dropped a stored proc on the designer 
and map the result of that to one of the generated types above.

The code file for ReportType is like so:

[DataContract]
[KnownType(typeof(BillableHoursReportType))]
[KnownType(typeof(Detail....))]
class ReportType
{
}

Hopefully, if we need a "report header" in the future we can just add it to 
ReportType.

Anyways, we have a service contract for IReporting, and a ReportManager 
implementation class.

public IList<ReportType> GetReport(string reportName, Criteria c);

The ReportManager will probably switch on the name to determine what the 
concrete report type is, then call into the provider.GetReport<T>(criteria) 
method.

So far when the service is hosted on IIS, I can navigate the WSDL and XSD 
documents and see that all derived report type classes are defined.

So, I'm presuming that all is going well. It's an experimental project and we 
decided to use LINQ in the data layer. I wasn't keen on exposing the classes 
generated in the LINQ to SQL Classes designer, so I just map that result set to 
one of our data contract types.

________________________________________
From: Discussion of advanced .NET topics. [EMAIL PROTECTED] On Behalf Of Ryan 
Heath [EMAIL PROTECTED]
Sent: Friday, December 14, 2007 1:28 PM
To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-DOTNET] Method that returns List<BaseClass>

Make the ctor static and you will not need the lock.
The CLR guarantees it will call the static ctor only once.

static ReportProviderSql()
{
  _reportFunctions = new
Dictionary<Type,Func<ReportCriteria,IList<ReportType>>>();
  _reportFunctions.Add(typeof(DetailByDateReportType), GetDetailByDate);
}

// Ryan

On Dec 14, 2007 8:02 PM, Ron Young <[EMAIL PROTECTED]> wrote:
> Yes it does. I'll have to consider that.
>
> Here is what I'm essentially going for.
>
> // client side:
> List<Report> detailByDateReports = 
> provider.GetReports<DetailByDateReport>(criteria);
> foreach (DetailByDateReport rpt in detailByDateReports)
>     // do something
>
> // the provider class, data layer
>    public class ReportProviderSql : IReportProvider
>    {
>        private static Dictionary<Type, Func<ReportCriteria, 
> IList<ReportType>>> _reportFunctions = null;
>        private static object _syncLock = new object();
>        public ReportProviderSql()
>        {
>            if (_reportFunctions == null)
>            {
>                lock(_syncLock)
>                {
>                    if (_reportFunctions == null)
>                    {
>                        _reportFunctions = new 
> Dictionary<Type,Func<ReportCriteria,IList<ReportType>>>();
>                        _reportFunctions.Add(typeof(DetailByDateReportType), 
> GetDetailByDate);
>                    }
>                }
>            }
>        }
>        #region IReportProvider Members
>        public IList<T> GetReport<T>(ReportCriteria criteria) where T : 
> ReportType
>        {
>            Type t = typeof(T);
>            if (_reportFunctions.ContainsKey(t))
>            {
>                return _reportFunctions[t].Invoke(criteria) as IList<T>;
>            }
>            return null;
>        }
>        #endregion
>        private static IList<ReportType> GetDetailByDate(ReportCriteria 
> criteria)
>        {
>            List<ReportType> resultset = new List<ReportType>();
>
>            ReportsDataContext db = new ReportsDataContext();
>
>            var query = db.proc_RptDetailByDate(criteria.StartDate,
>                criteria.EndDate, criteria.EmployeeID, criteria.ProjectID);
>
>            foreach (var item in query)
>            {
>                DetailByDateReportType rpt = new DetailByDateReportType();
>                rpt.Employee = item.Employee;
>                rpt.Project = item.Project;
>                rpt.Date = item.Date;
>                rpt.Comments = item.Comments;
>                rpt.Time = item.Time;
>                rpt.Duration = item.Duration ?? 0.0M;
>                resultset.Add(rpt);
>            }
>
>            db.Dispose();
>
>            return resultset;
>        }
>    }
>
> ________________________________________
> From: Discussion of advanced .NET topics. [EMAIL PROTECTED] On Behalf Of Bob 
> Provencher [EMAIL PROTECTED]
> Sent: Friday, December 14, 2007 12:58 PM
>
> To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
> Subject: Re: [ADVANCED-DOTNET] Method that returns List<BaseClass>
>
> I think if someone puts a Report in your list, which it's type implies is
> allowed, your foreach will throw an invalid cast exception.
>
> -----Original Message-----
> From: Discussion of advanced .NET topics.
> [mailto:[EMAIL PROTECTED] On Behalf Of Ron Young
> Sent: Friday, December 14, 2007 1:46 PM
> To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
> Subject: Re: [ADVANCED-DOTNET] Method that returns List<BaseClass>
>
> Indeed it does. Thank you.
>
> I was under the impression that if the method that returned derived reports
> ultimately returned a list of the base report, then the client would get the
> properties defined in the base report.
>
> But it's up to the client to determine what types of reports are in the
> list, so this works:
>
> // client-side
> List<Report> reports = provider.GetReports();
> foreach (ReportA item in reports)
>    WL(item.MyName);
>
> ===================================
> This list is hosted by DevelopMentor(R)  http://www.develop.com
>
> View archives and manage your subscription(s) at http://discuss.develop.com
>
> ===================================
> This list is hosted by DevelopMentor(R)  http://www.develop.com
>
> View archives and manage your subscription(s) at http://discuss.develop.com
>

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to