Peter
Peter

Reputation: 5332

Generic Object Creation Always Returning Nulls

EDIT I updated my question for completeness.

I have incoming REST calls from an iPHone client. It is meant to consume type-specific objects in response to generic requests. For example:

http://localhost:81/dashboard/group/id/0

returns data from the Regions type

http://localhost:81/dashboard/group/id/1

returns data from the Customers type

http://localhost:81/dashboard/group/id/2

returns data from the Users type

and so on.

The WCF Dashboard.svc service exposes a base method GetGroupById which I use to determine and return the type-specific response:

public class Dashboard : GroupBase, Contracts.IDashboardService { private string name = String.Empty;

    public Dashboard() : base()
    {

        if (!ServiceSecurityContext.Current.PrimaryIdentity.IsAuthenticated)
            throw new WebException("Unauthorized: Class: Dashboard, Method: Dashboard()",
                System.Net.HttpStatusCode.Forbidden);

        name = ServiceSecurityContext.Current.PrimaryIdentity.Name;

    }

    public override System.IO.Stream GetGroupById(string id)
    {
        return base.GetGroupById(id);
    }

}

Now, inside my abstract base class the GetGroupById has a switch/case statement that populates and returns unique data transfer objects based on the corresponding groupid parameter:

            public abstract class GroupBase
{

    protected GroupBase () { }

    public virtual Stream GetGroupById(string id)
    {
         // I have tried assigning response to null or, in this case,
         // assigning it to a random service object. I have also tried
         // IObjectFactory response; The last fails at compile-time and
         // the other two always produce null  
         IObjectFactory response = 
            ObjectFactory<IObjectFactory, UserService>.Create();  

        var groupId = System.Convert.ToInt32(id);
        var serializer = new JavaScriptSerializer();

        byte[] bytes = null;

        var message = String.Empty;

        try
        {

            switch (groupId)
            {
                case 0: // regions

                    response = ObjectFactory<IObjectFactory, RegionService>.Create();
                    break;

                case 1: // customers

                    response = ObjectFactory<IObjectFactory, CustomerService>.Create();
                    break;

                case 2: // users
                    response = ObjectFactory<IObjectFactory, UserService>.Create();
                    break;
            }

        }

        catch (EngageException oops)
        {
            message = oops.Message;
        }



        bytes = Encoding.UTF8.GetBytes(serializer.Serialize(response));

        return new MemoryStream(bytes);

    }

}

A customer ObjectFactory class is used to create the type-specific object:

public static class ObjectFactory where T : F, new() { public static F Create() { return new T(); } }

WHERE I AM HAVING PROBLEMS IS what is going on under the hood of my ObjectFactory. I am always getting ** null ** back. For example, consider the following REST HTTP GET:

http://localhost:81/dashboard/group/id/2

The above command is asking for a JSON string of all Users in the database. Accordingly, the UserService class is passed into the ObjectFactory method.

  public class UserService : IObjectFactory
{
    DomainObjectsDto IObjectFactory.Children
    {
        get
        {

            return new Contracts.DomainObjectsDto(UserRepository
                                .GetAllUsers().Select
                                (p => new Contracts.DomainObjectDto
                                 {
                                     Title = GroupTypes.Customer.ToString(),
                                     Id = p.CustomerId.ToString(),
                                     Type = p.GetType().ToString()
                                 }));
        }

    }

    string IObjectFactory.Method
    {
        get;
        set;
    }

    string IObjectFactory.Status
    {
        get;
        set;
    }

    etc...

And, the readonly Get property gets data from the UserRepository, populates the Data Transfer Object (illustrated below)

[DataContract]
public class DomainObjectDto
{
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public string Id { get; set; }
    [DataMember]
    public string Type { get; set; }
}

   [CollectionDataContract]
    public class DomainObjectsDto : List<DomainObjectDto>
    {
        public DomainObjectsDto() { }
        public DomainObjectsDto(IEnumerable<DomainObjectDto> source) : base(source) { }
    }

And should return the serialized JSON string of User data to the client. But, my generic type T in my object factory class is always null:

 public static F Create()
    {
        return new T(); // <-- always null!
    }

Any ideas??

Upvotes: 0

Views: 324

Answers (3)

Marc Gravell
Marc Gravell

Reputation: 1062770

Change the line IObjectFactory response = null; to remove the default, i.e. IObjectFactory response;. Now the compiler will tell you if there is a branch that doesn't assign it (of course, it can't tell you if you assign to null somehow). Note also that there are at least 2 ways of getting null from a new (etc), but these are edge cases - I doubt they are contributing (mentioned for completeness only).

Upvotes: 0

Chris Hogan
Chris Hogan

Reputation: 868

It's a good idea to add default cases to your switch statements, like:

default: 
  throw new Exception( "groupId " + groupId + " not found" );

Upvotes: 0

James Michael Hare
James Michael Hare

Reputation: 38397

Hard to tell without seeing the invocation of your factory in context, but my gut feel is that groupId is not in the switch range and thus you are getting the null you defaulted it to. I would add a default case and throw an out of range exception and see if that's your problem.

Upvotes: 2

Related Questions