У меня есть эта служба перезапуска, которую я хочу иметь возможность вызывать для всех классов в определенном пространстве имен или сборке.И мне нужно знать, для какого типа он вызывается внутри операции.Короче говоря, я хочу шаблон, который позволяет оба из них:
../MyClass1/some/further/spec
../MyClass2/some/further/spec
Я хочу, чтобы мои шаблоны URI выглядели примерно так:
/{type}/some/further/{info}
И моя операция будет выглядеть примерно так:
public void ClassSpecificOfSomeFurtherSpec(Type type, string info)
Я предполагаю, что нет способа сделать что-то вроде следующего, что, я думаю, это то, чего я действительно пытаюсь достичь.В конце концов, я думаю, что генерики должны быть определены во время компиляции.Но это освещает проблему:
public void ClassSpecificOfSomeFurtherSpec<type>(string info)
Проблема здесь в том, что вход для класса - это короткое имя типа, а не полное имя, что означает Type.GetType (class, true, true)не сработаетЕсли бы я мог использовать это в своей пользовательской десериализации, и все было бы хорошо.Но так как этого не произойдет, я не хочу жестко кодировать свое пространство имен в моей общей десериализации, поскольку это сделает его совершенно неуниверсальным.
Если бы я добавил IParameterInspector, мог бы я затем изменить параметр(или только проверять это), и прикрепить пространство имен до того, как произойдет десериализация, или же порядок будет обратным?
У меня такое чувство, что я слишком усложняю вещи.Есть ли простой способ сделать то, что я упустил, или какая-то действительно убедительная причина, почему я не должен так обобщать свои услуги?
Суть в том, что я хочу избежать этогокод для каждой отдельной операции:
public Response ClassSpecificOfSomeFurtherSpec(string type, string spec)
{
Type theType = Type.GetType("My.NameSpaced."+type, true, true);
//.. and the stuff that does things
}
Update1
Итак, я нашел этот замечательный пост в блоге Карлоса, описывающий, как добавить опцию превращения IParameterInspectorв улучшенную версию, которая также может изменять параметры.В блоге он только изменяет возвращаемые значения.Что я хотел сделать, это изменить входное значение.Итак, я добавил эту возможность и добавил свой класс-модификатор:
public class EntityParameterModifier : IParameterModifier
{
public OperationDescription Description { get; private set; }
public EntityParameterModifier(OperationDescription description)
{
Description = description;
}
public object BeforeCall(string operationName, ref object[] inputs)
{
var parts = Description.Messages[0].Body.Parts;
for (int i = 0; i < parts.Count; i++)
{
if (parts[i].Type == typeof(Type) && inputs[i].GetType() == typeof(string))
inputs[i] = EntityStringToType((string)inputs[i]);
}
return null;
}
public void AfterCall(string operationName, object[] outputs, ref object returnValue, object correlationState) { }
private Type EntityStringToType(string entityString)
{
Assembly assembly = Assembly.GetAssembly(typeof(Entity));
Type type = (from t in assembly.GetTypes()
where t.Name == entityString || t.FullName == entityString
select t).SingleOrDefault<Type>();
return type;
}
}
Но, конечно, они добавили несколько блоков, чтобы помешать вам делать такие вещи:
[InvalidOperationException: Operation 'ClassSpecificOfSomeFurtherSpec' in contract
'IMyServiceContract' has a path variable named 'type' which does not have type 'string'.
Variables for UriTemplate path segments must have type 'string'.]
System.ServiceModel.Dispatcher.UriTemplateClientFormatter.Populate(Dictionary`2& pathMapping, Dictionary`2& queryMapping, Int32& totalNumUTVars, UriTemplate& uriTemplate, OperationDescription operationDescription, QueryStringConverter qsc, String contractName) +1128
Что указывает мне в совершенно новом направлении.Есть ли способ переопределить UriTemplateClientFormatter или связанные классы для достижения того, что я хочу?