দেরীতে বাইন্ডিং গতিশীলভাবে নিয়ামক প্রবেশের পরে মডেলগুলি সমাধান করুন


9

আমি একটি নিয়ামকের কোনও ক্রিয়াকলাপে প্রবেশের পরে কোনও মডেল সমাধানের উপায় অনুসন্ধান করছি, সমস্যাটি বর্ণনা করার সহজ উপায় হ'ল:

public DTO[] Get(string filterName)
{
    //How can I do this
    this.Resolve<MyCustomType>("MyParamName");
}

আমি কেন চেষ্টা করছি সে সম্পর্কে আরও তথ্যের সন্ধান করা হলে আপনি পুরো ছবিটি পেতে পড়া চালিয়ে যেতে পারেন

টি এল; ডিআর

আমি কোনও পরামিতি নাম দিয়ে একটি মডেলকে একটি অনুরোধ সমাধানের একটি উপায় সন্ধান করছি, যা সর্বদা ক্যোয়ারী স্ট্রিং থেকে সমাধান করা হবে কীভাবে আমি প্রারম্ভ থেকেই ফিল্টারগুলিকে গতিশীলভাবে নিবন্ধ করতে পারি। আমার একটি ক্লাস রয়েছে যা আমার ফিল্টারগুলি নিবন্ধকরণ করতে চলেছে।

আমার স্টার্টআপ ক্লাসে আমি আমার বিশ্রাম সার্ভিসগুলির সাথে ফিল্টারগুলি গতিশীলভাবে নিবন্ধিত করতে সক্ষম হতে চাই। আমার কাছে একটি বিকল্প রয়েছে যা আমি আমার কাস্টম কন্ট্রোলার ফিচারপ্রভাইডারের কাছে যাচ্ছি যা দেখতে মোটামুটি এরকম দেখাচ্ছে:

public class DynamicControllerOptions<TEntity, TDTO>
{
    Dictionary<string, Func<HttpContext, Expression<Func<TEntity, bool>>>> _funcNameToEndpointResolverMap
        = new Dictionary<string, Func<HttpContext, Expression<Func<TEntity, bool>>>>();
    Dictionary<string, List<ParameterOptions>> _filterParamsMap = new Dictionary<string, List<ParameterOptions>>();

    public void AddFilter(string filterName, Expression<Func<TEntity, bool>> filter)
    {
        this._funcNameToEndpointResolverMap.Add(filterName, (httpContext) =>  filter);
    }
    public void AddFilter<T1>(string filterName, Func<T1, Expression<Func<TEntity, bool>>> filterResolver,
        string param1Name = "param1")
    {
        var parameters = new List<ParameterOptions> { new ParameterOptions { Name = param1Name, Type = typeof(T1) } };
        this._filterParamsMap.Add(filterName, parameters);
        this._funcNameToEndpointResolverMap.Add(filterName, (httpContext) => {
            T1 parameter = this.ResolveParameterFromContext<T1>(httpContext, param1Name);
            var filter = filterResolver(parameter);
            return filter;
        });
    }
}

আমার কন্ট্রোলার অপশনগুলি ট্র্যাক করে রাখবে এবং এগুলি প্যাজিং এন্ডপয়েন্টস এবং ওডেটার জন্য ফিল্টার সরবরাহ করতে ব্যবহার করবে।

public class DynamicControllerBase<TEntity, TDTO> : ControllerBase
{
    protected DynamicControllerOptions<TEntity, TDTO> _options;
    //...

    public TDTO[] GetList(string filterName = "")
    {
        Expression<Func<TEntity, bool>> filter = 
            this.Options.ResolveFilter(filterName, this.HttpContext);
        var entities = this._context.DbSet<TEntity>().Where(filter).ToList();
        return entities.ToDTO<TDTO>();
    }
}

এইচটিটিপি কনটেক্সট প্রদত্ত কোনও মডেলকে কীভাবে গতিশীলভাবে সমাধান করতে হবে তা বুঝতে আমার সমস্যা হচ্ছে, আমি মডেলটি পাওয়ার জন্য এই জাতীয় কিছু করার চিন্তা করব তবে এটি সিউডো কোড যা কাজ করে না

private Task<T> ResolveParameterFromContext<T>(HttpContext httpContext, string parameterName)
{
    //var modelBindingContext = httpContext.ToModelBindingContext();
    //var modelBinder = httpContext.Features.OfType<IModelBinder>().Single();
    //return modelBinder.BindModelAsync<T>(parameterName);
}

উত্সে খননের পরে, আমি কিছু প্রতিশ্রুতিবদ্ধ জিনিসগুলি দেখেছি মডেলবাইন্ডফ্যাক্টরি এবং কন্ট্রোলার অ্যাকশনআইভোকার এই ক্লাসগুলি মডেল বাইন্ডিংয়ের জন্য পাইপলাইনে ব্যবহৃত হয়,

আমি কোয়েরিস্ট্রিং থেকে প্যারামিটারের নামটি সমাধান করার জন্য একটি সাধারণ ইন্টারফেসটি প্রকাশ করার আশা করব, এরকম কিছু:

ModelBindingContext context = new ModelBindingContext();
return context.GetValueFor<T>("MyParamName");

যাইহোক, আমি মডেল বাইন্ডার থেকে কোনও মডেল সমাধান করার একমাত্র উপায় হ'ল নকল নিয়ন্ত্রণকারী বর্ণনাকারী তৈরি করা এবং প্রচুর পরিমাণে জিনিস উপহাস করা।

আমি কীভাবে আমার কনটোলারের মধ্যে দেরীতে আবদ্ধ প্যারামিটারগুলি গ্রহণ করতে পারি?


2
আমি এর জন্য কোনও ব্যবহার দেখতে পাচ্ছি না। তবুও আপনি যদি স্ট্রিং প্যারামিটারের ভিত্তিতে মডেলটিকে বাঁধতে পারেন তবে .... আপনি getValueFor <T> এর মতো জেনেরিক পদ্ধতি ব্যবহার করতে পারবেন না কারণ টি অবশ্যই একটি সঙ্কলনের সময় সমাধান করা উচিত .... এর অর্থ এই যে কলকারীকে অবশ্যই জানতে হবে সংকলন সময়ে টি টাইপ যা গতিবদ্ধভাবে টাইপ বাঁধাইয়ের উদ্দেশ্যকে পরাস্ত করবে। এর অর্থ হ'ল ডায়নামিককন্ট্রোলারবেসের উত্তরাধিকারীর অবশ্যই টিডিটিও'র ধরণটি জানা উচিত .... আপনি যে জিনিসটি চেষ্টা করতে পারেন তা হল প্যারামিটারে জেএসওএন গ্রহণ করা এবং ডায়নামিককন্ট্রোলারবেসের প্রতিটি প্রয়োগটি স্ট্রিংকে একটি মডেল এবং বিপরীতক্রমে ডিজিটালাইজ করা উচিত।
জোনাথন আলফারো

@ ডারকোনেক্ট যদি আপনি 'অ্যাডফিল্টার' পদ্ধতিটি দেখেন তবে আপনার টাইপ করা জেনেরিক পরামিতিগুলি রয়েছে যা আপনি ফানকস নিবন্ধকরণের সময় বন্ধ হয়ে যায়। এটি কিছুটা বিভ্রান্তিকর তবে আমি আপনাকে এটির বাস্তবের আশ্বাস দিচ্ছি এবং কাজ করতে পারে
5

আমি জসন-এ প্লাগ করতে চাই না, কারণ ওয়েবপ্যাফিকভাবে প্রাকৃতিকভাবে পরামিতিগুলি সমাধান করার উপায়টি আমি পরিবর্তন করতে চাই না
5

আপনি যদি ব্যবহারের ক্ষেত্রে এবং বাস্তব জীবনের দৃশ্যের বিষয়ে যেখানে আরও কিছু ব্যাখ্যা করতে চান যেখানে এই ধরণের কার্যকারিতা প্রয়োজন, এটি অনেক সাহায্য করবে। সম্ভবত একটি সহজ সমাধান উপলব্ধ আছে .. কে জানে। আমার স্ব হিসাবে, আমি মাঝে মাঝে জিনিসগুলিকে জটিল করতে পছন্দ করি .. শুধু বলি ..
মিঃ ব্লন্ড

@ মিঃ ব্লন্ড আমার কাছে একটি জেনেরিক বিশ্রাম পরিষেবা রয়েছে যা ক্রুড সরবরাহ করে এবং তালিকার কার্যকারিতা পান। কখনও কখনও আমার পরিষেবাগুলি তালিকা থেকে তথ্য ফিল্টার করা প্রয়োজন, তবে ফিল্টার সরবরাহ করার জন্য আমার যা দরকার তার একটি সম্পূর্ণ পরিষেবা লিখতে চাই না
জননি 5

উত্তর:


2

আমি আপনার চিন্তার সাথে একমত

পরিষেবাদিগুলির তালিকা পেতে তথ্য ফিল্টার করা দরকার, তবে ফিল্টার সরবরাহ করার জন্য আমার যা প্রয়োজন তার একটি সম্পূর্ণ পরিষেবা লিখতে চাই না

প্রতিটি সম্ভাব্য সংমিশ্রণের জন্য কেন একটি উইজেট / ফিল্টার / শেষ পয়েন্ট লিখবেন?

সমস্ত ডেটা / সম্পত্তি পেতে কেবল প্রাথমিক ক্রিয়াকলাপ সরবরাহ করুন। তারপরে গ্রাফকিউএল ব্যবহার করুন শেষ ব্যবহারকারীকে তাদের প্রয়োজনীয়তার জন্য এটি ( মডেল ) ফিল্টার করার অনুমতি দিন ।

গ্রাফকিউএল থেকে

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools


আমি গ্রাফকিউএল ব্যবহারের বিষয়ে বিবেচনা করছি তবে আমি আমার বর্তমান বাস্তবায়নের সাথে খুব জড়িত রয়েছি
5

2

আমরা এটি করেছি, আমাদের কোডগুলি এই সাইটটিকে রেফারেন্স করে: https://prideparrot.com/blog/archive/2012/6/gotchas_in_explicit_model_binding

বিশেষত, আমাদের কোডটির দিকে তাকিয়ে, কৌশলটি কীভাবে আপনার নিয়ামক পদ্ধতিতে একটি ফর্মকলাকশন গ্রহণ করছে এবং তারপরে মডেল বাইন্ডার, মডেল এবং ফর্ম ডেটা ব্যবহার করছে:

লিঙ্ক থেকে নেওয়া উদাহরণ:

public ActionResult Save(FormCollection form)
{
var empType = Type.GetType("Example.Models.Employee");
var emp = Activator.CreateInstance(empType);

var binder = Binders.GetBinder(empType);

  var bindingContext = new ModelBindingContext()
  {
    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => emp, empType),
    ModelState = ModelState,
    ValueProvider = form
  };      

  binder.BindModel(ControllerContext, bindingContext);

  if (ModelState.IsValid)
  {
   _empRepo.Save(emp);

    return RedirectToAction("Index");
  }

return View();
}

(দ্রষ্টব্য: সাইটটি ডাউন বলে মনে হচ্ছে, আর্কাইভ.আরগে লিঙ্কটি রয়েছে)


আপনার সহায়তার জন্য ধন্যবাদ, বর্তমানে আমি এমভিসি ব্যবহার করছি না, যেমন (1 টিরও বেশি ইনপুট প্যারামিটার থাকতে পারে) নামটি দিয়ে প্যারামিটারগুলি সমাধান করতে হবে resolve অতিরিক্ত হিসাবে আমি। নেট-কোর ব্যবহার করি আমার মনে হয় এটি পুরানো সংস্করণ। নেট এর জন্য লেখা হয়েছে। দয়া করে পদ্ধতিটির স্টাবটি পূরণ করুন: উত্তরটি স্বীকার করার জন্য:this.Resolve<MyCustomType>("MyParamName");
জননি 5

যেহেতু আমার এটিকে ন্যূনতমভাবে প্রজনন করার পরিবেশ নেই, তাই আমি এটি করতে সক্ষম হবো না - ডটনেটকোর প্রয়োজনীয়তা হারিয়ে যাওয়ার জন্য আমি ক্ষমাপ্রার্থী।
ব্রায়ান

আমি এটি অনুবাদ করতে পারি। নেট-কোর এটি ঠিক আছে, আপনি যদি প্যারামিটার নাম দিয়ে কীভাবে সমাধান করবেন তা আমাকে দেখান আমি গ্রহণ করব
5

আমি যে উত্তরটি চেয়েছিলাম তার নিকটতম জিনিস এটি তাই আমি আপনাকে
অনুগ্রহটি

0

আমি গতিশীল নিয়ামক লেখার শেষ করেছি। আশেপাশের কাজ হিসাবে সমস্যাটি সমাধান করা।

private static TypeBuilder GetTypeBuilder(string assemblyName)
{
    var assemName = new AssemblyName(assemblyName);
    var assemBuilder = AssemblyBuilder.DefineDynamicAssembly(assemName, AssemblyBuilderAccess.Run);
    // Create a dynamic module in Dynamic Assembly.
    var moduleBuilder = assemBuilder.DefineDynamicModule("DynamicModule");
    var tb = moduleBuilder.DefineType(assemblyName,
            TypeAttributes.Public |
            TypeAttributes.Class |
            TypeAttributes.AutoClass |
            TypeAttributes.AnsiClass |
            TypeAttributes.BeforeFieldInit |
            TypeAttributes.AutoLayout,
            null);

    return tb;
}

আমি আপাতত পদ্ধতিতে ফানকে কোডিং করছি তবে আমি নিশ্চিত আপনি যদি প্রয়োজন হয় তবে কীভাবে এটি পাস করবেন তা আপনি নির্ধারণ করতে পারেন I'm

public static Type CompileResultType(string typeSignature)
{
    TypeBuilder tb = GetTypeBuilder(typeSignature);

    tb.SetParent(typeof(DynamicControllerBase));

    ConstructorBuilder ctor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

    // For this controller, I only want a Get method to server Get request
    MethodBuilder myGetMethod =
        tb.DefineMethod("Get",
            MethodAttributes.Public,
            typeof(String), new Type[] { typeof(Test), typeof(String) });

    // Define parameters
    var parameterBuilder = myGetMethod.DefineParameter(
        position: 1, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
        attributes: ParameterAttributes.None,
        strParamName: "test"
    );
    var attributeBuilder
        = new CustomAttributeBuilder(typeof(FromServicesAttribute).GetConstructor(Type.EmptyTypes), Type.EmptyTypes);
    parameterBuilder.SetCustomAttribute(attributeBuilder);

    // Define parameters
    myGetMethod.DefineParameter(
        position: 2, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
        attributes: ParameterAttributes.None,
        strParamName: "stringParam"
    );

    // Generate IL for method.
    ILGenerator myMethodIL = myGetMethod.GetILGenerator();
    Func<string, string> method = (v) => "Poop";

    Func<Test, string, string> method1 = (v, s) => v.Name + s;

    myMethodIL.Emit(OpCodes.Jmp, method1.Method);
    myMethodIL.Emit(OpCodes.Ret);

    return tb.CreateType();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.