GetInheritedContracts() private method

private GetInheritedContracts ( ) : Collection
return Collection
Exemplo n.º 1
0
        internal static ContractDescription GetContractInternal(Type givenContractType, Type givenServiceType, Type serviceTypeForCallback)
        {
            if (givenContractType == null)
            {
                throw new ArgumentNullException("givenContractType");
            }
            // FIXME: serviceType should be used for specifying attributes like OperationBehavior.

            Type exactContractType       = null;
            ServiceContractAttribute sca = null;
            Dictionary <Type, ServiceContractAttribute> contracts =
                GetServiceContractAttributes(serviceTypeForCallback ?? givenServiceType ?? givenContractType);

            if (contracts.ContainsKey(givenContractType))
            {
                exactContractType = givenContractType;
                sca = contracts [givenContractType];
            }
            else
            {
                foreach (Type t in contracts.Keys)
                {
                    if (t.IsAssignableFrom(givenContractType))
                    {
                        if (t.IsAssignableFrom(exactContractType))                          // exact = IDerived, t = IBase
                        {
                            continue;
                        }
                        if (sca != null && (exactContractType == null || !exactContractType.IsAssignableFrom(t)))                          // t = IDerived, exact = IBase
                        {
                            throw new InvalidOperationException("The contract type of " + givenContractType + " is ambiguous: can be either " + exactContractType + " or " + t);
                        }
                        exactContractType = t;
                        sca = contracts [t];
                    }
                }
            }
            if (exactContractType == null)
            {
                exactContractType = givenContractType;
            }
            if (sca == null)
            {
                if (serviceTypeForCallback != null)
                {
                    sca = contracts.Values.First();
                }
                else
                {
                    return(null);                    // no contract
                }
            }
            string name = sca.Name ?? exactContractType.Name;
            string ns   = sca.Namespace ?? "http://tempuri.org/";

            ContractDescription cd =
                new ContractDescription(name, ns);

            cd.ContractType         = exactContractType;
            cd.CallbackContractType = sca.CallbackContract;
            cd.SessionMode          = sca.SessionMode;
            if (sca.ConfigurationName != null)
            {
                cd.ConfigurationName = sca.ConfigurationName;
            }
            else
            {
                cd.ConfigurationName = exactContractType.FullName;
            }
            if (sca.HasProtectionLevel)
            {
                cd.ProtectionLevel = sca.ProtectionLevel;
            }

            foreach (var icd in cd.GetInheritedContracts())
            {
                FillOperationsForInterface(icd, icd.ContractType, givenServiceType, false);
                foreach (var od in icd.Operations)
                {
                    if (!cd.Operations.Any(o => o.Name == od.Name && o.SyncMethod == od.SyncMethod &&
                                           o.BeginMethod == od.BeginMethod && o.InCallbackContract == od.InCallbackContract))
                    {
                        cd.Operations.Add(od);
                    }
                }
            }

            FillOperationsForInterface(cd, cd.ContractType, givenServiceType, false);

            if (cd.CallbackContractType != null)
            {
                FillOperationsForInterface(cd, cd.CallbackContractType, null, true);
            }

            // FIXME: enable this when I found where this check is needed.

            /*
             * if (cd.Operations.Count == 0)
             *      throw new InvalidOperationException (String.Format ("The service contract type {0} has no operation. At least one operation must exist.", contractType));
             */
            return(cd);
        }
Exemplo n.º 2
0
		internal static ContractDescription GetContractInternal (Type givenContractType, Type givenServiceType, Type serviceTypeForCallback)
		{
			// FIXME: serviceType should be used for specifying attributes like OperationBehavior.

			Type exactContractType = null;
			ServiceContractAttribute sca = null;
			Dictionary<Type, ServiceContractAttribute> contracts = 
				GetServiceContractAttributes (serviceTypeForCallback ?? givenServiceType ?? givenContractType);
			if (contracts.ContainsKey (givenContractType)) {
				exactContractType = givenContractType;
				sca = contracts [givenContractType];
			} else {
				foreach (Type t in contracts.Keys)
					if (t.IsAssignableFrom(givenContractType)) {
						if (t.IsAssignableFrom (exactContractType)) // exact = IDerived, t = IBase
							continue;
						if (sca != null && (exactContractType == null || !exactContractType.IsAssignableFrom (t))) // t = IDerived, exact = IBase
							throw new InvalidOperationException ("The contract type of " + givenContractType + " is ambiguous: can be either " + exactContractType + " or " + t);
						exactContractType = t;
						sca = contracts [t];
					}
			}
			if (exactContractType == null)
				exactContractType = givenContractType;
			if (sca == null) {
				if (serviceTypeForCallback != null)
					sca = contracts.Values.First ();
				else
					return null; // no contract
			}
			string name = sca.Name ?? exactContractType.Name;
			string ns = sca.Namespace ?? "http://tempuri.org/";

			ContractDescription cd =
				new ContractDescription (name, ns);
			cd.ContractType = exactContractType;
			cd.CallbackContractType = sca.CallbackContract;
			cd.SessionMode = sca.SessionMode;
			if (sca.ConfigurationName != null)
				cd.ConfigurationName = sca.ConfigurationName;
			else
				cd.ConfigurationName = exactContractType.FullName;
			if (sca.HasProtectionLevel)
				cd.ProtectionLevel = sca.ProtectionLevel;

			foreach (var icd in cd.GetInheritedContracts ()) {
				FillOperationsForInterface (icd, icd.ContractType, givenServiceType, false);
				foreach (var od in icd.Operations)
					cd.Operations.Add (od);
			}
			
			FillOperationsForInterface (cd, cd.ContractType, givenServiceType, false);
			
			if (cd.CallbackContractType != null && cd.CallbackContractType != cd.ContractType)
				FillOperationsForInterface (cd, cd.CallbackContractType, null, true);

			// FIXME: enable this when I found where this check is needed.
			/*
			if (cd.Operations.Count == 0)
				throw new InvalidOperationException (String.Format ("The service contract type {0} has no operation. At least one operation must exist.", contractType));
			*/
			return cd;
		}